Change to the spec...missed a consistency property. Adding timing option.
[repair.git] / Repair / RepairInterpreter / GenericHashtable.cc
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <values.h>
7 #include "GenericHashtable.h"
8 //#include "dmalloc.h"
9
10 int genputtable(struct genhashtable *ht, void * key, void * object) {
11   unsigned int bin=genhashfunction(ht,key);
12   struct genpointerlist * newptrlist=(struct genpointerlist *) new genpointerlist;
13   newptrlist->src=key;
14   newptrlist->object=object;
15   newptrlist->next=ht->bins[bin];
16   newptrlist->inext=NULL;
17   /* maintain linked list of ht entries for iteration*/
18   if (ht->last==NULL) {
19     ht->last=newptrlist;
20     ht->list=newptrlist;
21     newptrlist->iprev=NULL;
22   } else {
23     ht->last->inext=newptrlist;
24     newptrlist->iprev=ht->last;
25     ht->last=newptrlist;
26   }
27   ht->bins[bin]=newptrlist;
28   ht->counter++;
29   if(ht->counter>ht->currentsize&&ht->currentsize!=MAXINT) {
30     /* Expand hashtable */
31     long newcurrentsize=(ht->currentsize<(MAXINT/2))?ht->currentsize*2:MAXINT;
32     long oldcurrentsize=ht->currentsize;
33     struct genpointerlist **newbins=(struct genpointerlist **) new genpointerlist*[newcurrentsize];
34     struct genpointerlist **oldbins=ht->bins;
35     for(long j=0;j<newcurrentsize;j++) newbins[j]=NULL;
36     long i;
37     ht->currentsize=newcurrentsize;
38     for(i=0;i<oldcurrentsize;i++) {
39       struct genpointerlist * tmpptr=oldbins[i];
40       while(tmpptr!=NULL) {
41         int hashcode=genhashfunction(ht, tmpptr->src);
42         struct genpointerlist *nextptr=tmpptr->next;
43         tmpptr->next=newbins[hashcode];
44         newbins[hashcode]=tmpptr;
45         tmpptr=nextptr;
46       }
47     }
48     ht->bins=newbins;
49     delete[](oldbins);
50   }
51   return 1;
52 }
53
54 int hashsize(struct genhashtable *ht) {
55   return ht->counter;
56 }
57
58 void * gengettable(struct genhashtable *ht, void * key) {
59   struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
60   while(ptr!=NULL) {
61     if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key)))
62       return ptr->object;
63     ptr=ptr->next;
64   }
65   printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p\n",key);
66   return NULL;
67 }
68
69 void * getnext(struct genhashtable *ht, void * key) {
70   struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
71   while(ptr!=NULL) {
72     if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key)))
73       if (ptr->inext!=NULL) {
74         return ptr->inext->src;
75       } else
76         return NULL;
77     ptr=ptr->next;
78   }
79   printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p...\n Likely concurrent removal--bad user!!!\n",key);
80   return NULL;
81 }
82
83 int gencontains(struct genhashtable *ht, void * key) {
84   struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
85   //printf("In gencontains2\n");fflush(NULL);
86   while(ptr!=NULL) {
87     if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key)))
88       return 1;
89     ptr=ptr->next;
90   }
91   return 0;
92 }
93
94
95 void genfreekey(struct genhashtable *ht, void * key) {
96   struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
97
98   if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key))) {
99     ht->bins[genhashfunction(ht,key)]=ptr->next;
100
101     if (ptr==ht->last)
102       ht->last=ptr->iprev;
103
104     if (ptr==ht->list)
105       ht->list=ptr->inext;
106
107     if (ptr->iprev!=NULL)
108       ptr->iprev->inext=ptr->inext;
109     if (ptr->inext!=NULL)
110       ptr->inext->iprev=ptr->iprev;
111     
112     delete(ptr);
113     ht->counter--;
114     return;
115   }
116   while(ptr->next!=NULL) {
117     if (((ht->comp_function==NULL)&&(ptr->next->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->next->src,key))) {
118       struct genpointerlist *tmpptr=ptr->next;
119       ptr->next=tmpptr->next;
120       if (tmpptr==ht->list)
121         ht->list=tmpptr->inext;
122       if (tmpptr==ht->last)
123         ht->last=tmpptr->iprev;
124       if (tmpptr->iprev!=NULL)
125         tmpptr->iprev->inext=tmpptr->inext;
126       if (tmpptr->inext!=NULL)
127         tmpptr->inext->iprev=tmpptr->iprev;
128       delete(tmpptr);
129       ht->counter--;
130       return;
131     }
132     ptr=ptr->next;
133   }
134   printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p\n",key);
135 }
136
137 unsigned int genhashfunction(struct genhashtable *ht, void * key) {
138   if (ht->hash_function==NULL)
139     return ((long unsigned int)key) % ht->currentsize;
140   else
141     return ((*ht->hash_function)(key)) % ht->currentsize;
142 }
143
144 struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *, void *)) {
145   struct genhashtable *ght=(struct genhashtable *) new genhashtable;
146   struct genpointerlist **gpl=(struct genpointerlist **) new genpointerlist *[geninitialnumbins];
147   for(int i=0;i<geninitialnumbins;i++)
148     gpl[i]=NULL;
149   ght->hash_function=hash_function;
150   ght->comp_function=comp_function;
151   ght->currentsize=geninitialnumbins;
152   ght->bins=gpl;
153   ght->counter=0;
154   ght->list=NULL;
155   ght->last=NULL;
156   return ght;
157 }
158
159 void genfreehashtable(struct genhashtable * ht) {
160   int i;
161   for (i=0;i<ht->currentsize;i++) {
162     if (ht->bins[i]!=NULL) {
163       struct genpointerlist *genptr=ht->bins[i];
164       while(genptr!=NULL) {
165         struct genpointerlist *tmpptr=genptr->next;
166         delete(genptr);
167         genptr=tmpptr;
168       }
169     }
170   }
171   delete[](ht->bins);
172   delete(ht);
173 }
174
175 struct geniterator * gengetiterator(struct genhashtable *ht) {
176   struct geniterator *gi=new geniterator();
177   gi->ptr=ht->list;
178   return gi;
179 }
180
181 void * gennext(struct geniterator *it) {
182   struct genpointerlist *curr=it->ptr;
183   if (curr==NULL)
184     return NULL;
185   if (it->finished&&(curr->inext==NULL))
186     return NULL;
187   if (it->finished) {
188     it->ptr=curr->inext;
189     return it->ptr->src;
190   }
191   if(curr->inext!=NULL)
192     it->ptr=curr->inext;
193   else
194     it->finished=true; /* change offsetting scheme */
195   return curr->src;
196 }
197
198 void genfreeiterator(struct geniterator *it) {
199   delete(it);
200 }