annotate trunk/chipmunkd/cpHashSet.d @ 4:7ebbd4d05553

initial commit
author Extrawurst
date Thu, 02 Dec 2010 02:11:26 +0100
parents
children df4ebc8add66
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
1
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
2 // written in the D programming language
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
3
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
4 module chipmunkd.cpHashSet;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
5
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
6 import chipmunkd.chipmunk;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
7 import chipmunkd.chipmunk_types_h;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
8 import chipmunkd.cpArray;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
9 import chipmunkd.prime;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
10
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
11 // cpHashSet uses a chained hashtable implementation.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
12 // Other than the transformation functions, there is nothing fancy going on.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
13
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
14 // cpHashSetBin's form the linked lists in the chained hash table.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
15 struct cpHashSetBin {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
16 // Pointer to the element.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
17 void *elt;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
18 // Hash value of the element.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
19 cpHashValue hash;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
20 // Next element in the chain.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
21 cpHashSetBin *next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
22 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
23
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
24 // Equality function. Returns true if ptr is equal to elt.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
25 alias cpBool function(void *ptr, void *elt) cpHashSetEqlFunc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
26 // Used by cpHashSetInsert(). Called to transform the ptr into an element.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
27 alias void* function(void *ptr, void *data) cpHashSetTransFunc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
28
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
29 struct cpHashSet {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
30 // Number of elements stored in the table.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
31 int entries;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
32 // Number of cells in the table.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
33 int size;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
34
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
35 cpHashSetEqlFunc eql;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
36 cpHashSetTransFunc trans;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
37
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
38 // Default value returned by cpHashSetFind() when no element is found.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
39 // Defaults to null.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
40 void *default_value;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
41
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
42 // The table and recycled bins
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
43 cpHashSetBin **table;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
44 cpHashSetBin *pooledBins;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
45
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
46 cpArray *allocatedBuffers;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
47 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
48
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
49 alias void function(void *elt, void *data) cpHashSetIterFunc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
50 alias cpBool function(void *elt, void *data) cpHashSetFilterFunc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
51
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
52 static void freeWrap(void *ptr, void *unused){cpfree(ptr);}
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
53
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
54 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
55 cpHashSetDestroy(cpHashSet *set)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
56 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
57 // Free the table.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
58 cpfree(set.table);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
59
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
60 cpArrayEach(set.allocatedBuffers, &freeWrap, null);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
61 cpArrayFree(set.allocatedBuffers);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
62 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
63
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
64 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
65 cpHashSetFree(cpHashSet *set)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
66 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
67 if(set){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
68 cpHashSetDestroy(set);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
69 cpfree(set);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
70 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
71 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
72
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
73 cpHashSet *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
74 cpHashSetAlloc()
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
75 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
76 return cast(cpHashSet *)cpcalloc(1, cpHashSet.sizeof);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
77 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
78
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
79 cpHashSet *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
80 cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
81 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
82 set.size = next_prime(size);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
83 set.entries = 0;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
84
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
85 set.eql = eqlFunc;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
86 set.trans = trans;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
87
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
88 set.default_value = null;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
89
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
90 set.table = cast(cpHashSetBin **)cpcalloc(set.size, (cpHashSetBin *).sizeof);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
91 set.pooledBins = null;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
92
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
93 set.allocatedBuffers = cpArrayNew(0);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
94
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
95 return set;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
96 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
97
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
98 cpHashSet *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
99 cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
100 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
101 return cpHashSetInit(cpHashSetAlloc(), size, eqlFunc, trans);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
102 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
103
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
104 static int
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
105 setIsFull(cpHashSet *set)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
106 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
107 return (set.entries >= set.size);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
108 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
109
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
110 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
111 cpHashSetResize(cpHashSet *set)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
112 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
113 // Get the next approximate doubled prime.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
114 int newSize = next_prime(set.size + 1);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
115 // Allocate a new table.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
116 cpHashSetBin **newTable = cast(cpHashSetBin **)cpcalloc(newSize, (cpHashSetBin *).sizeof);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
117
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
118 // Iterate over the chains.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
119 for(int i=0; i<set.size; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
120 // Rehash the bins into the new table.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
121 cpHashSetBin *bin = set.table[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
122 while(bin){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
123 cpHashSetBin *next = bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
124
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
125 int idx = bin.hash%newSize;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
126 bin.next = newTable[idx];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
127 newTable[idx] = bin;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
128
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
129 bin = next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
130 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
131 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
132
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
133 cpfree(set.table);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
134
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
135 set.table = newTable;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
136 set.size = newSize;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
137 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
138
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
139 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
140 recycleBin(cpHashSet *set, cpHashSetBin *bin)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
141 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
142 bin.next = set.pooledBins;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
143 set.pooledBins = bin;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
144 bin.elt = null;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
145 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
146
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
147 static cpHashSetBin *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
148 getUnusedBin(cpHashSet *set)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
149 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
150 cpHashSetBin *bin = set.pooledBins;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
151
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
152 if(bin){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
153 set.pooledBins = bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
154 return bin;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
155 } else {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
156 // Pool is exhausted, make more
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
157 int count = CP_BUFFER_BYTES/cpHashSetBin.sizeof;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
158 assert(count!=0, "Buffer size is too small.");
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
159
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
160 cpHashSetBin *buffer = cast(cpHashSetBin *)cpmalloc(CP_BUFFER_BYTES);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
161 cpArrayPush(set.allocatedBuffers, buffer);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
162
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
163 // push all but the first one, return the first instead
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
164 for(int i=1; i<count; i++) recycleBin(set, buffer + i);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
165 return buffer;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
166 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
167 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
168
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
169 void *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
170 cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
171 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
172 int idx = hash%set.size;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
173
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
174 // Find the bin with the matching element.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
175 cpHashSetBin *bin = set.table[idx];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
176 while(bin && !set.eql(ptr, bin.elt))
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
177 bin = bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
178
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
179 // Create it necessary.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
180 if(!bin){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
181 bin = getUnusedBin(set);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
182 bin.hash = hash;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
183 bin.elt = set.trans(ptr, data); // Transform the pointer.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
184
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
185 bin.next = set.table[idx];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
186 set.table[idx] = bin;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
187
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
188 set.entries++;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
189
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
190 // Resize the set if it's full.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
191 if(setIsFull(set))
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
192 cpHashSetResize(set);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
193 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
194
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
195 return bin.elt;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
196 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
197
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
198 void *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
199 cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
200 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
201 int idx = hash%set.size;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
202
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
203 // Pointer to the previous bin pointer.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
204 cpHashSetBin **prev_ptr = &set.table[idx];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
205 // Pointer the the current bin.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
206 cpHashSetBin *bin = set.table[idx];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
207
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
208 // Find the bin
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
209 while(bin && !set.eql(ptr, bin.elt)){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
210 prev_ptr = &bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
211 bin = bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
212 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
213
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
214 // Remove it if it exists.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
215 if(bin){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
216 // Update the previous bin pointer to point to the next bin.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
217 (*prev_ptr) = bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
218 set.entries--;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
219
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
220 void *return_value = bin.elt;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
221
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
222 recycleBin(set, bin);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
223
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
224 return return_value;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
225 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
226
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
227 return null;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
228 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
229
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
230 void *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
231 cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
232 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
233 int idx = hash%set.size;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
234 cpHashSetBin *bin = set.table[idx];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
235 while(bin && !set.eql(ptr, bin.elt))
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
236 bin = bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
237
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
238 return (bin ? bin.elt : set.default_value);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
239 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
240
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
241 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
242 cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
243 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
244 for(int i=0; i<set.size; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
245 cpHashSetBin *bin = set.table[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
246 while(bin){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
247 cpHashSetBin *next = bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
248 func(bin.elt, data);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
249 bin = next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
250 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
251 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
252 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
253
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
254 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
255 cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
256 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
257 // Iterate over all the chains.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
258 for(int i=0; i<set.size; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
259 // The rest works similarly to cpHashSetRemove() above.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
260 cpHashSetBin **prev_ptr = &set.table[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
261 cpHashSetBin *bin = set.table[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
262 while(bin){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
263 cpHashSetBin *next = bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
264
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
265 if(func(bin.elt, data)){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
266 prev_ptr = &bin.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
267 } else {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
268 (*prev_ptr) = next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
269
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
270 set.entries--;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
271 recycleBin(set, bin);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
272 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
273
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
274 bin = next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
275 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
276 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
277 }