Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.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 * pkix_pl_hashtable.c | |
6 * | |
7 * Hashtable Object Functions | |
8 * | |
9 */ | |
10 | |
11 #include "pkix_pl_hashtable.h" | |
12 | |
13 /* --Private-Structure-------------------------------------------- */ | |
14 | |
15 struct PKIX_PL_HashTableStruct { | |
16 pkix_pl_PrimHashTable *primHash; | |
17 PKIX_PL_Mutex *tableLock; | |
18 PKIX_UInt32 maxEntriesPerBucket; | |
19 }; | |
20 | |
21 /* --Private-Functions-------------------------------------------- */ | |
22 | |
23 #define PKIX_MUTEX_UNLOCK(mutex) \ | |
24 do { \ | |
25 if (mutex && lockedMutex == (PKIX_PL_Mutex *)(mutex)) { \ | |
26 pkixTempResult = \ | |
27 PKIX_PL_Mutex_Unlock((mutex), plContext); \ | |
28 PORT_Assert(pkixTempResult == NULL); \ | |
29 if (pkixTempResult) { \ | |
30 PKIX_DoAddError(&stdVars, pkixTempResult, plContext); \ | |
31 pkixTempResult = NULL; \ | |
32 } \ | |
33 lockedMutex = NULL; \ | |
34 } else { \ | |
35 PORT_Assert(lockedMutex == NULL); \ | |
36 }\ | |
37 } while (0) | |
38 | |
39 | |
40 #define PKIX_MUTEX_LOCK(mutex) \ | |
41 do { \ | |
42 if (mutex){ \ | |
43 PORT_Assert(lockedMutex == NULL); \ | |
44 PKIX_CHECK(PKIX_PL_Mutex_Lock((mutex), plContext), \ | |
45 PKIX_MUTEXLOCKFAILED); \ | |
46 lockedMutex = (mutex); \ | |
47 } \ | |
48 } while (0) | |
49 | |
50 /* | |
51 * FUNCTION: pkix_pl_HashTable_Destroy | |
52 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
53 */ | |
54 static PKIX_Error * | |
55 pkix_pl_HashTable_Destroy( | |
56 PKIX_PL_Object *object, | |
57 void *plContext) | |
58 { | |
59 PKIX_PL_HashTable *ht = NULL; | |
60 pkix_pl_HT_Elem *item = NULL; | |
61 PKIX_UInt32 i; | |
62 | |
63 PKIX_ENTER(HASHTABLE, "pkix_pl_HashTable_Destroy"); | |
64 PKIX_NULLCHECK_ONE(object); | |
65 | |
66 PKIX_CHECK(pkix_CheckType(object, PKIX_HASHTABLE_TYPE, plContext), | |
67 PKIX_OBJECTNOTHASHTABLE); | |
68 | |
69 ht = (PKIX_PL_HashTable*) object; | |
70 | |
71 /* DecRef every object in the primitive hash table */ | |
72 for (i = 0; i < ht->primHash->size; i++) { | |
73 for (item = ht->primHash->buckets[i]; | |
74 item != NULL; | |
75 item = item->next) { | |
76 PKIX_DECREF(item->key); | |
77 PKIX_DECREF(item->value); | |
78 } | |
79 } | |
80 | |
81 PKIX_CHECK(pkix_pl_PrimHashTable_Destroy(ht->primHash, plContext), | |
82 PKIX_PRIMHASHTABLEDESTROYFAILED); | |
83 | |
84 PKIX_DECREF(ht->tableLock); | |
85 | |
86 cleanup: | |
87 | |
88 PKIX_RETURN(HASHTABLE); | |
89 } | |
90 | |
91 /* | |
92 * FUNCTION: pkix_pl_HashTable_RegisterSelf | |
93 * DESCRIPTION: | |
94 * Registers PKIX_HASHTABLE_TYPE and its related functions with systemClasses[] | |
95 * THREAD SAFETY: | |
96 * Not Thread Safe - for performance and complexity reasons | |
97 * | |
98 * Since this function is only called by PKIX_PL_Initialize, which should | |
99 * only be called once, it is acceptable that this function is not | |
100 * thread-safe. | |
101 */ | |
102 PKIX_Error * | |
103 pkix_pl_HashTable_RegisterSelf( | |
104 void *plContext) | |
105 { | |
106 | |
107 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
108 pkix_ClassTable_Entry entry; | |
109 | |
110 PKIX_ENTER(HASHTABLE, "pkix_pl_HashTable_RegisterSelf"); | |
111 | |
112 entry.description = "HashTable"; | |
113 entry.objCounter = 0; | |
114 entry.typeObjectSize = sizeof(PKIX_PL_HashTable); | |
115 entry.destructor = pkix_pl_HashTable_Destroy; | |
116 entry.equalsFunction = NULL; | |
117 entry.hashcodeFunction = NULL; | |
118 entry.toStringFunction = NULL; | |
119 entry.comparator = NULL; | |
120 entry.duplicateFunction = NULL; | |
121 | |
122 systemClasses[PKIX_HASHTABLE_TYPE] = entry; | |
123 | |
124 PKIX_RETURN(HASHTABLE); | |
125 } | |
126 | |
127 /* --Public-Functions------------------------------------------------------- */ | |
128 | |
129 /* | |
130 * FUNCTION: PKIX_PL_HashTable_Create (see comments in pkix_pl_system.h) | |
131 */ | |
132 PKIX_Error * | |
133 PKIX_PL_HashTable_Create( | |
134 PKIX_UInt32 numBuckets, | |
135 PKIX_UInt32 maxEntriesPerBucket, | |
136 PKIX_PL_HashTable **pResult, | |
137 void *plContext) | |
138 { | |
139 PKIX_PL_HashTable *hashTable = NULL; | |
140 | |
141 PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Create"); | |
142 PKIX_NULLCHECK_ONE(pResult); | |
143 | |
144 if (numBuckets == 0) { | |
145 PKIX_ERROR(PKIX_NUMBUCKETSEQUALSZERO); | |
146 } | |
147 | |
148 /* Allocate a new hashtable */ | |
149 PKIX_CHECK(PKIX_PL_Object_Alloc | |
150 (PKIX_HASHTABLE_TYPE, | |
151 sizeof (PKIX_PL_HashTable), | |
152 (PKIX_PL_Object **)&hashTable, | |
153 plContext), | |
154 PKIX_COULDNOTCREATEHASHTABLEOBJECT); | |
155 | |
156 /* Create the underlying primitive hash table type */ | |
157 PKIX_CHECK(pkix_pl_PrimHashTable_Create | |
158 (numBuckets, &hashTable->primHash, plContext), | |
159 PKIX_PRIMHASHTABLECREATEFAILED); | |
160 | |
161 /* Create a lock for this table */ | |
162 PKIX_CHECK(PKIX_PL_Mutex_Create(&hashTable->tableLock, plContext), | |
163 PKIX_ERRORCREATINGTABLELOCK); | |
164 | |
165 hashTable->maxEntriesPerBucket = maxEntriesPerBucket; | |
166 | |
167 *pResult = hashTable; | |
168 | |
169 cleanup: | |
170 | |
171 if (PKIX_ERROR_RECEIVED){ | |
172 PKIX_DECREF(hashTable); | |
173 } | |
174 | |
175 PKIX_RETURN(HASHTABLE); | |
176 } | |
177 | |
178 /* | |
179 * FUNCTION: PKIX_PL_HashTable_Add (see comments in pkix_pl_system.h) | |
180 */ | |
181 PKIX_Error * | |
182 PKIX_PL_HashTable_Add( | |
183 PKIX_PL_HashTable *ht, | |
184 PKIX_PL_Object *key, | |
185 PKIX_PL_Object *value, | |
186 void *plContext) | |
187 { | |
188 PKIX_PL_Mutex *lockedMutex = NULL; | |
189 PKIX_PL_Object *deletedKey = NULL; | |
190 PKIX_PL_Object *deletedValue = NULL; | |
191 PKIX_UInt32 hashCode; | |
192 PKIX_PL_EqualsCallback keyComp; | |
193 PKIX_UInt32 bucketSize = 0; | |
194 | |
195 PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Add"); | |
196 | |
197 #if !defined(PKIX_OBJECT_LEAK_TEST) | |
198 PKIX_NULLCHECK_THREE(ht, key, value); | |
199 #else | |
200 PKIX_NULLCHECK_TWO(key, value); | |
201 | |
202 if (ht == NULL) { | |
203 PKIX_RETURN(HASHTABLE); | |
204 } | |
205 #endif | |
206 /* Insert into primitive hashtable */ | |
207 | |
208 PKIX_CHECK(PKIX_PL_Object_Hashcode(key, &hashCode, plContext), | |
209 PKIX_OBJECTHASHCODEFAILED); | |
210 | |
211 PKIX_CHECK(pkix_pl_Object_RetrieveEqualsCallback | |
212 (key, &keyComp, plContext), | |
213 PKIX_OBJECTRETRIEVEEQUALSCALLBACKFAILED); | |
214 | |
215 PKIX_MUTEX_LOCK(ht->tableLock); | |
216 | |
217 PKIX_CHECK(pkix_pl_PrimHashTable_GetBucketSize | |
218 (ht->primHash, | |
219 hashCode, | |
220 &bucketSize, | |
221 plContext), | |
222 PKIX_PRIMHASHTABLEGETBUCKETSIZEFAILED); | |
223 | |
224 if (ht->maxEntriesPerBucket != 0 && | |
225 bucketSize >= ht->maxEntriesPerBucket) { | |
226 /* drop the last one in the bucket */ | |
227 PKIX_CHECK(pkix_pl_PrimHashTable_RemoveFIFO | |
228 (ht->primHash, | |
229 hashCode, | |
230 (void **) &deletedKey, | |
231 (void **) &deletedValue, | |
232 plContext), | |
233 PKIX_PRIMHASHTABLEGETBUCKETSIZEFAILED); | |
234 PKIX_DECREF(deletedKey); | |
235 PKIX_DECREF(deletedValue); | |
236 } | |
237 | |
238 PKIX_CHECK(pkix_pl_PrimHashTable_Add | |
239 (ht->primHash, | |
240 (void *)key, | |
241 (void *)value, | |
242 hashCode, | |
243 keyComp, | |
244 plContext), | |
245 PKIX_PRIMHASHTABLEADDFAILED); | |
246 | |
247 PKIX_INCREF(key); | |
248 PKIX_INCREF(value); | |
249 PKIX_MUTEX_UNLOCK(ht->tableLock); | |
250 | |
251 /* | |
252 * we don't call PKIX_PL_InvalidateCache here b/c we have | |
253 * not implemented toString or hashcode for this Object | |
254 */ | |
255 | |
256 cleanup: | |
257 | |
258 PKIX_MUTEX_UNLOCK(ht->tableLock); | |
259 | |
260 PKIX_RETURN(HASHTABLE); | |
261 } | |
262 | |
263 /* | |
264 * FUNCTION: PKIX_PL_HashTable_Remove (see comments in pkix_pl_system.h) | |
265 */ | |
266 PKIX_Error * | |
267 PKIX_PL_HashTable_Remove( | |
268 PKIX_PL_HashTable *ht, | |
269 PKIX_PL_Object *key, | |
270 void *plContext) | |
271 { | |
272 PKIX_PL_Mutex *lockedMutex = NULL; | |
273 PKIX_PL_Object *origKey = NULL; | |
274 PKIX_PL_Object *value = NULL; | |
275 PKIX_UInt32 hashCode; | |
276 PKIX_PL_EqualsCallback keyComp; | |
277 | |
278 PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Remove"); | |
279 | |
280 #if !defined(PKIX_OBJECT_LEAK_TEST) | |
281 PKIX_NULLCHECK_TWO(ht, key); | |
282 #else | |
283 PKIX_NULLCHECK_ONE(key); | |
284 | |
285 if (ht == NULL) { | |
286 PKIX_RETURN(HASHTABLE); | |
287 } | |
288 #endif | |
289 | |
290 PKIX_CHECK(PKIX_PL_Object_Hashcode(key, &hashCode, plContext), | |
291 PKIX_OBJECTHASHCODEFAILED); | |
292 | |
293 PKIX_CHECK(pkix_pl_Object_RetrieveEqualsCallback | |
294 (key, &keyComp, plContext), | |
295 PKIX_OBJECTRETRIEVEEQUALSCALLBACKFAILED); | |
296 | |
297 PKIX_MUTEX_LOCK(ht->tableLock); | |
298 | |
299 /* Remove from primitive hashtable */ | |
300 PKIX_CHECK(pkix_pl_PrimHashTable_Remove | |
301 (ht->primHash, | |
302 (void *)key, | |
303 hashCode, | |
304 keyComp, | |
305 (void **)&origKey, | |
306 (void **)&value, | |
307 plContext), | |
308 PKIX_PRIMHASHTABLEREMOVEFAILED); | |
309 | |
310 PKIX_MUTEX_UNLOCK(ht->tableLock); | |
311 | |
312 PKIX_DECREF(origKey); | |
313 PKIX_DECREF(value); | |
314 | |
315 /* | |
316 * we don't call PKIX_PL_InvalidateCache here b/c we have | |
317 * not implemented toString or hashcode for this Object | |
318 */ | |
319 | |
320 cleanup: | |
321 | |
322 PKIX_MUTEX_UNLOCK(ht->tableLock); | |
323 | |
324 PKIX_RETURN(HASHTABLE); | |
325 } | |
326 | |
327 /* | |
328 * FUNCTION: PKIX_PL_HashTable_Lookup (see comments in pkix_pl_system.h) | |
329 */ | |
330 PKIX_Error * | |
331 PKIX_PL_HashTable_Lookup( | |
332 PKIX_PL_HashTable *ht, | |
333 PKIX_PL_Object *key, | |
334 PKIX_PL_Object **pResult, | |
335 void *plContext) | |
336 { | |
337 PKIX_PL_Mutex *lockedMutex = NULL; | |
338 PKIX_UInt32 hashCode; | |
339 PKIX_PL_EqualsCallback keyComp; | |
340 PKIX_PL_Object *result = NULL; | |
341 | |
342 PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Lookup"); | |
343 | |
344 #if !defined(PKIX_OBJECT_LEAK_TEST) | |
345 PKIX_NULLCHECK_THREE(ht, key, pResult); | |
346 #else | |
347 PKIX_NULLCHECK_TWO(key, pResult); | |
348 | |
349 if (ht == NULL) { | |
350 PKIX_RETURN(HASHTABLE); | |
351 } | |
352 #endif | |
353 | |
354 PKIX_CHECK(PKIX_PL_Object_Hashcode(key, &hashCode, plContext), | |
355 PKIX_OBJECTHASHCODEFAILED); | |
356 | |
357 PKIX_CHECK(pkix_pl_Object_RetrieveEqualsCallback | |
358 (key, &keyComp, plContext), | |
359 PKIX_OBJECTRETRIEVEEQUALSCALLBACKFAILED); | |
360 | |
361 PKIX_MUTEX_LOCK(ht->tableLock); | |
362 | |
363 /* Lookup in primitive hashtable */ | |
364 PKIX_CHECK(pkix_pl_PrimHashTable_Lookup | |
365 (ht->primHash, | |
366 (void *)key, | |
367 hashCode, | |
368 keyComp, | |
369 (void **)&result, | |
370 plContext), | |
371 PKIX_PRIMHASHTABLELOOKUPFAILED); | |
372 | |
373 PKIX_INCREF(result); | |
374 PKIX_MUTEX_UNLOCK(ht->tableLock); | |
375 | |
376 *pResult = result; | |
377 | |
378 cleanup: | |
379 | |
380 PKIX_MUTEX_UNLOCK(ht->tableLock); | |
381 | |
382 PKIX_RETURN(HASHTABLE); | |
383 } |