Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/base/hash.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 /* | |
6 * hash.c | |
7 * | |
8 * This is merely a couple wrappers around NSPR's PLHashTable, using | |
9 * the identity hash and arena-aware allocators. | |
10 * This is a copy of ckfw/hash.c, with modifications to use NSS types | |
11 * (not Cryptoki types). Would like for this to be a single implementation, | |
12 * but doesn't seem like it will work. | |
13 */ | |
14 | |
15 #ifndef BASE_H | |
16 #include "base.h" | |
17 #endif /* BASE_H */ | |
18 | |
19 #include "prbit.h" | |
20 | |
21 /* | |
22 * nssHash | |
23 * | |
24 * nssHash_Create | |
25 * nssHash_Destroy | |
26 * nssHash_Add | |
27 * nssHash_Remove | |
28 * nssHash_Count | |
29 * nssHash_Exists | |
30 * nssHash_Lookup | |
31 * nssHash_Iterate | |
32 */ | |
33 | |
34 struct nssHashStr { | |
35 NSSArena *arena; | |
36 PRBool i_alloced_arena; | |
37 PRLock *mutex; | |
38 | |
39 /* | |
40 * The invariant that mutex protects is: | |
41 * The count accurately reflects the hashtable state. | |
42 */ | |
43 | |
44 PLHashTable *plHashTable; | |
45 PRUint32 count; | |
46 }; | |
47 | |
48 static PLHashNumber | |
49 nss_identity_hash | |
50 ( | |
51 const void *key | |
52 ) | |
53 { | |
54 PRUint32 i = (PRUint32)key; | |
55 PR_ASSERT(sizeof(PLHashNumber) == sizeof(PRUint32)); | |
56 return (PLHashNumber)i; | |
57 } | |
58 | |
59 static PLHashNumber | |
60 nss_item_hash | |
61 ( | |
62 const void *key | |
63 ) | |
64 { | |
65 unsigned int i; | |
66 PLHashNumber h; | |
67 NSSItem *it = (NSSItem *)key; | |
68 h = 0; | |
69 for (i=0; i<it->size; i++) | |
70 h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)it->data)[i]; | |
71 return h; | |
72 } | |
73 | |
74 static int | |
75 nss_compare_items(const void *v1, const void *v2) | |
76 { | |
77 PRStatus ignore; | |
78 return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore); | |
79 } | |
80 | |
81 /* | |
82 * nssHash_create | |
83 * | |
84 */ | |
85 NSS_IMPLEMENT nssHash * | |
86 nssHash_Create | |
87 ( | |
88 NSSArena *arenaOpt, | |
89 PRUint32 numBuckets, | |
90 PLHashFunction keyHash, | |
91 PLHashComparator keyCompare, | |
92 PLHashComparator valueCompare | |
93 ) | |
94 { | |
95 nssHash *rv; | |
96 NSSArena *arena; | |
97 PRBool i_alloced; | |
98 | |
99 #ifdef NSSDEBUG | |
100 if( arenaOpt && PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { | |
101 nss_SetError(NSS_ERROR_INVALID_POINTER); | |
102 return (nssHash *)NULL; | |
103 } | |
104 #endif /* NSSDEBUG */ | |
105 | |
106 if (arenaOpt) { | |
107 arena = arenaOpt; | |
108 i_alloced = PR_FALSE; | |
109 } else { | |
110 arena = nssArena_Create(); | |
111 i_alloced = PR_TRUE; | |
112 } | |
113 | |
114 rv = nss_ZNEW(arena, nssHash); | |
115 if( (nssHash *)NULL == rv ) { | |
116 goto loser; | |
117 } | |
118 | |
119 rv->mutex = PZ_NewLock(nssILockOther); | |
120 if( (PZLock *)NULL == rv->mutex ) { | |
121 goto loser; | |
122 } | |
123 | |
124 rv->plHashTable = PL_NewHashTable(numBuckets, | |
125 keyHash, keyCompare, valueCompare, | |
126 &nssArenaHashAllocOps, arena); | |
127 if( (PLHashTable *)NULL == rv->plHashTable ) { | |
128 (void)PZ_DestroyLock(rv->mutex); | |
129 goto loser; | |
130 } | |
131 | |
132 rv->count = 0; | |
133 rv->arena = arena; | |
134 rv->i_alloced_arena = i_alloced; | |
135 | |
136 return rv; | |
137 loser: | |
138 (void)nss_ZFreeIf(rv); | |
139 return (nssHash *)NULL; | |
140 } | |
141 | |
142 /* | |
143 * nssHash_CreatePointer | |
144 * | |
145 */ | |
146 NSS_IMPLEMENT nssHash * | |
147 nssHash_CreatePointer | |
148 ( | |
149 NSSArena *arenaOpt, | |
150 PRUint32 numBuckets | |
151 ) | |
152 { | |
153 return nssHash_Create(arenaOpt, numBuckets, | |
154 nss_identity_hash, PL_CompareValues, PL_CompareValues); | |
155 } | |
156 | |
157 /* | |
158 * nssHash_CreateString | |
159 * | |
160 */ | |
161 NSS_IMPLEMENT nssHash * | |
162 nssHash_CreateString | |
163 ( | |
164 NSSArena *arenaOpt, | |
165 PRUint32 numBuckets | |
166 ) | |
167 { | |
168 return nssHash_Create(arenaOpt, numBuckets, | |
169 PL_HashString, PL_CompareStrings, PL_CompareStrings); | |
170 } | |
171 | |
172 /* | |
173 * nssHash_CreateItem | |
174 * | |
175 */ | |
176 NSS_IMPLEMENT nssHash * | |
177 nssHash_CreateItem | |
178 ( | |
179 NSSArena *arenaOpt, | |
180 PRUint32 numBuckets | |
181 ) | |
182 { | |
183 return nssHash_Create(arenaOpt, numBuckets, | |
184 nss_item_hash, nss_compare_items, PL_CompareValues); | |
185 } | |
186 | |
187 /* | |
188 * nssHash_Destroy | |
189 * | |
190 */ | |
191 NSS_IMPLEMENT void | |
192 nssHash_Destroy | |
193 ( | |
194 nssHash *hash | |
195 ) | |
196 { | |
197 (void)PZ_DestroyLock(hash->mutex); | |
198 PL_HashTableDestroy(hash->plHashTable); | |
199 if (hash->i_alloced_arena) { | |
200 nssArena_Destroy(hash->arena); | |
201 } else { | |
202 nss_ZFreeIf(hash); | |
203 } | |
204 } | |
205 | |
206 /* | |
207 * nssHash_Add | |
208 * | |
209 */ | |
210 NSS_IMPLEMENT PRStatus | |
211 nssHash_Add | |
212 ( | |
213 nssHash *hash, | |
214 const void *key, | |
215 const void *value | |
216 ) | |
217 { | |
218 PRStatus error = PR_FAILURE; | |
219 PLHashEntry *he; | |
220 | |
221 PZ_Lock(hash->mutex); | |
222 | |
223 he = PL_HashTableAdd(hash->plHashTable, key, (void *)value); | |
224 if( (PLHashEntry *)NULL == he ) { | |
225 nss_SetError(NSS_ERROR_NO_MEMORY); | |
226 } else if (he->value != value) { | |
227 nss_SetError(NSS_ERROR_HASH_COLLISION); | |
228 } else { | |
229 hash->count++; | |
230 error = PR_SUCCESS; | |
231 } | |
232 | |
233 (void)PZ_Unlock(hash->mutex); | |
234 | |
235 return error; | |
236 } | |
237 | |
238 /* | |
239 * nssHash_Remove | |
240 * | |
241 */ | |
242 NSS_IMPLEMENT void | |
243 nssHash_Remove | |
244 ( | |
245 nssHash *hash, | |
246 const void *it | |
247 ) | |
248 { | |
249 PRBool found; | |
250 | |
251 PZ_Lock(hash->mutex); | |
252 | |
253 found = PL_HashTableRemove(hash->plHashTable, it); | |
254 if( found ) { | |
255 hash->count--; | |
256 } | |
257 | |
258 (void)PZ_Unlock(hash->mutex); | |
259 return; | |
260 } | |
261 | |
262 /* | |
263 * nssHash_Count | |
264 * | |
265 */ | |
266 NSS_IMPLEMENT PRUint32 | |
267 nssHash_Count | |
268 ( | |
269 nssHash *hash | |
270 ) | |
271 { | |
272 PRUint32 count; | |
273 | |
274 PZ_Lock(hash->mutex); | |
275 | |
276 count = hash->count; | |
277 | |
278 (void)PZ_Unlock(hash->mutex); | |
279 | |
280 return count; | |
281 } | |
282 | |
283 /* | |
284 * nssHash_Exists | |
285 * | |
286 */ | |
287 NSS_IMPLEMENT PRBool | |
288 nssHash_Exists | |
289 ( | |
290 nssHash *hash, | |
291 const void *it | |
292 ) | |
293 { | |
294 void *value; | |
295 | |
296 PZ_Lock(hash->mutex); | |
297 | |
298 value = PL_HashTableLookup(hash->plHashTable, it); | |
299 | |
300 (void)PZ_Unlock(hash->mutex); | |
301 | |
302 if( (void *)NULL == value ) { | |
303 return PR_FALSE; | |
304 } else { | |
305 return PR_TRUE; | |
306 } | |
307 } | |
308 | |
309 /* | |
310 * nssHash_Lookup | |
311 * | |
312 */ | |
313 NSS_IMPLEMENT void * | |
314 nssHash_Lookup | |
315 ( | |
316 nssHash *hash, | |
317 const void *it | |
318 ) | |
319 { | |
320 void *rv; | |
321 | |
322 PZ_Lock(hash->mutex); | |
323 | |
324 rv = PL_HashTableLookup(hash->plHashTable, it); | |
325 | |
326 (void)PZ_Unlock(hash->mutex); | |
327 | |
328 return rv; | |
329 } | |
330 | |
331 struct arg_str { | |
332 nssHashIterator fcn; | |
333 void *closure; | |
334 }; | |
335 | |
336 static PRIntn | |
337 nss_hash_enumerator | |
338 ( | |
339 PLHashEntry *he, | |
340 PRIntn index, | |
341 void *arg | |
342 ) | |
343 { | |
344 struct arg_str *as = (struct arg_str *)arg; | |
345 as->fcn(he->key, he->value, as->closure); | |
346 return HT_ENUMERATE_NEXT; | |
347 } | |
348 | |
349 /* | |
350 * nssHash_Iterate | |
351 * | |
352 * NOTE that the iteration function will be called with the hashtable locked. | |
353 */ | |
354 NSS_IMPLEMENT void | |
355 nssHash_Iterate | |
356 ( | |
357 nssHash *hash, | |
358 nssHashIterator fcn, | |
359 void *closure | |
360 ) | |
361 { | |
362 struct arg_str as; | |
363 as.fcn = fcn; | |
364 as.closure = closure; | |
365 | |
366 PZ_Lock(hash->mutex); | |
367 | |
368 PL_HashTableEnumerateEntries(hash->plHashTable, nss_hash_enumerator, &as); | |
369 | |
370 (void)PZ_Unlock(hash->mutex); | |
371 | |
372 return; | |
373 } |