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 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)