Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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_primhash.c
6 *
7 * Primitive (non-object) Hashtable Functions
8 *
9 */
10
11 #include "pkix_pl_primhash.h"
12
13 /* --Private-Functions---------------------------------------- */
14
15 /*
16 * FUNCTION: pkix_pl_KeyComparator_Default
17 * DESCRIPTION:
18 *
19 * Compares the integer pointed to by "firstKey" with the integer pointed to
20 * by "secondKey" for equality and stores the Boolean result at "pResult".
21 * This default key comparator assumes each key is a PKIX_UInt32, and it
22 * simply tests them for equality.
23 *
24 * PARAMETERS:
25 * "firstKey"
26 * Address of the first integer key to compare. Must be non-NULL.
27 * The EqualsCallback for this Object will be called.
28 * "secondKey"
29 * Address of the second integer key to compare. Must be non-NULL.
30 * "pResult"
31 * Address where Boolean will be stored. Must be non-NULL.
32 * "plContext"
33 * Platform-specific context pointer.
34 * THREAD SAFETY:
35 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
36 * RETURNS:
37 * Returns NULL if the function succeeds.
38 * Returns a Fatal Error if the function fails in an unrecoverable way.
39 */
40 static PKIX_Error *
41 pkix_pl_KeyComparator_Default(
42 PKIX_UInt32 *firstKey,
43 PKIX_UInt32 *secondKey,
44 PKIX_Boolean *pResult,
45 void *plContext)
46 {
47 /* Assume both keys are pointers to PKIX_UInt32 */
48 PKIX_UInt32 firstInt, secondInt;
49
50 PKIX_ENTER(HASHTABLE, "pkix_pl_KeyComparator_Default");
51 PKIX_NULLCHECK_THREE(firstKey, secondKey, pResult);
52
53 firstInt = *firstKey;
54 secondInt = *secondKey;
55
56 *pResult = (firstInt == secondInt)?PKIX_TRUE:PKIX_FALSE;
57
58 PKIX_RETURN(HASHTABLE);
59 }
60
61
62 /*
63 * FUNCTION: pkix_pl_PrimHashTable_Create
64 * DESCRIPTION:
65 *
66 * Creates a new PrimHashtable object with a number of buckets equal to
67 * "numBuckets" and stores the result at "pResult".
68 *
69 * PARAMETERS:
70 * "numBuckets"
71 * The number of hash table buckets. Must be non-zero.
72 * "pResult"
73 * Address where PrimHashTable pointer will be stored. Must be non-NULL.
74 * "plContext"
75 * Platform-specific context pointer.
76 * THREAD SAFETY:
77 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
78 * RETURNS:
79 * Returns NULL if the function succeeds.
80 * Returns a Fatal Error if the function fails in an unrecoverable way.
81 */
82 PKIX_Error *
83 pkix_pl_PrimHashTable_Create(
84 PKIX_UInt32 numBuckets,
85 pkix_pl_PrimHashTable **pResult,
86 void *plContext)
87 {
88 pkix_pl_PrimHashTable *primHashTable = NULL;
89 PKIX_UInt32 i;
90
91 PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Create");
92 PKIX_NULLCHECK_ONE(pResult);
93
94 if (numBuckets == 0) {
95 PKIX_ERROR(PKIX_NUMBUCKETSEQUALSZERO);
96 }
97
98 /* Allocate a new hashtable */
99 PKIX_CHECK(PKIX_PL_Malloc
100 (sizeof (pkix_pl_PrimHashTable),
101 (void **)&primHashTable,
102 plContext),
103 PKIX_MALLOCFAILED);
104
105 primHashTable->size = numBuckets;
106
107 /* Allocate space for the buckets */
108 PKIX_CHECK(PKIX_PL_Malloc
109 (numBuckets * sizeof (pkix_pl_HT_Elem*),
110 (void **)&primHashTable->buckets,
111 plContext),
112 PKIX_MALLOCFAILED);
113
114 for (i = 0; i < numBuckets; i++) {
115 primHashTable->buckets[i] = NULL;
116 }
117
118 *pResult = primHashTable;
119
120 cleanup:
121
122 if (PKIX_ERROR_RECEIVED){
123 PKIX_FREE(primHashTable);
124 }
125
126 PKIX_RETURN(HASHTABLE);
127 }
128
129 /*
130 * FUNCTION: pkix_pl_PrimHashTable_Add
131 * DESCRIPTION:
132 *
133 * Adds the value pointed to by "value" to the PrimHashTable pointed to by
134 * "ht" using the key pointed to by "key" and the hashCode value equal to
135 * "hashCode", using the function pointed to by "keyComp" to compare keys.
136 * Assumes the key is either a PKIX_UInt32 or a PKIX_PL_Object. If the value
137 * already exists in the hashtable, this function returns a non-fatal error.
138 *
139 * PARAMETERS:
140 * "ht"
141 * Address of PrimHashtable to insert into. Must be non-NULL.
142 * "key"
143 * Address of key. Typically a PKIX_UInt32 or PKIX_PL_Object.
144 * Must be non-NULL.
145 * "value"
146 * Address of Object to be added to PrimHashtable. Must be non-NULL.
147 * "hashCode"
148 * Hashcode value of the key.
149 * "keyComp"
150 * Address of function used to determine if two keys are equal.
151 * If NULL, pkix_pl_KeyComparator_Default is used.
152 * "plContext"
153 * Platform-specific context pointer.
154 * THREAD SAFETY:
155 * Not Thread Safe - assumes exclusive access to "ht"
156 * (see Thread Safety Definitions in Programmer's Guide)
157 * RETURNS:
158 * Returns NULL if the function succeeds.
159 * Returns a HashTable Error if the function fails in a non-fatal way.
160 * Returns a Fatal Error if the function fails in an unrecoverable way.
161 */
162 PKIX_Error *
163 pkix_pl_PrimHashTable_Add(
164 pkix_pl_PrimHashTable *ht,
165 void *key,
166 void *value,
167 PKIX_UInt32 hashCode,
168 PKIX_PL_EqualsCallback keyComp,
169 void *plContext)
170 {
171 pkix_pl_HT_Elem **elemPtr = NULL;
172 pkix_pl_HT_Elem *element = NULL;
173 PKIX_Boolean compResult = PKIX_FALSE;
174
175 PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Add");
176 PKIX_NULLCHECK_THREE(ht, key, value);
177
178 for (elemPtr = &((ht->buckets)[hashCode%ht->size]), element = *elemPtr;
179 element != NULL; elemPtr = &(element->next), element = *elemPtr) {
180
181 if (element->hashCode != hashCode){
182 /* no possibility of a match */
183 continue;
184 }
185
186 if (keyComp == NULL){
187 PKIX_CHECK(pkix_pl_KeyComparator_Default
188 ((PKIX_UInt32 *)key,
189 (PKIX_UInt32 *)(element->key),
190 &compResult,
191 plContext),
192 PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
193 } else {
194 PKIX_CHECK(keyComp
195 ((PKIX_PL_Object *)key,
196 (PKIX_PL_Object *)(element->key),
197 &compResult,
198 plContext),
199 PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
200 }
201
202 if ((element->hashCode == hashCode) &&
203 (compResult == PKIX_TRUE)){
204 /* Same key already exists in the table */
205 PKIX_ERROR(PKIX_ATTEMPTTOADDDUPLICATEKEY);
206 }
207 }
208
209 /* Next Element should be NULL at this point */
210 if (element != NULL) {
211 PKIX_ERROR(PKIX_ERRORTRAVERSINGBUCKET);
212 }
213
214 /* Create a new HT_Elem */
215 PKIX_CHECK(PKIX_PL_Malloc
216 (sizeof (pkix_pl_HT_Elem), (void **)elemPtr, plContext),
217 PKIX_MALLOCFAILED);
218
219 element = *elemPtr;
220
221 element->key = key;
222 element->value = value;
223 element->hashCode = hashCode;
224 element->next = NULL;
225
226 cleanup:
227
228 PKIX_RETURN(HASHTABLE);
229 }
230
231 /*
232 * FUNCTION: pkix_pl_PrimHashTable_Remove
233 * DESCRIPTION:
234 *
235 * Removes any objects with the key pointed to by "key" and hashCode value
236 * equal to "hashCode" from the PrimHashtable pointed to by "ht", using the
237 * function pointed to by "keyComp" to compare keys, and stores the object's
238 * value at "pResult". Assumes "key" is a PKIX_UInt32 or a PKIX_PL_Object.
239 * This function sets "pResult" to NULL if the key is not in the hashtable.
240 *
241 * PARAMETERS:
242 * "ht"
243 * Address of PrimHashtable to remove object. Must be non-NULL.
244 * "key"
245 * Address of key for lookup. Typically a PKIX_UInt32 or PKIX_PL_Object.
246 * Must be non-NULL.
247 * "value"
248 * Address of Object to be added to PrimHashtable. Must be non-NULL.
249 * "hashCode"
250 * Hashcode value of the key.
251 * "keyComp"
252 * Address of function used to determine if two keys are equal.
253 * If NULL, pkix_pl_KeyComparator_Default is used.
254 * "pResult"
255 * Address where value will be stored. Must be non-NULL.
256 * "plContext"
257 * Platform-specific context pointer.
258 * THREAD SAFETY:
259 * Not Thread Safe - assumes exclusive access to "ht"
260 * (see Thread Safety Definitions in Programmer's Guide)
261 * RETURNS:
262 * Returns NULL if the function succeeds.
263 * Returns a HashTable Error if the function fails in a non-fatal way.
264 * Returns a Fatal Error if the function fails in an unrecoverable way.
265 */
266 PKIX_Error *
267 pkix_pl_PrimHashTable_Remove(
268 pkix_pl_PrimHashTable *ht,
269 void *key,
270 PKIX_UInt32 hashCode,
271 PKIX_PL_EqualsCallback keyComp,
272 void **pKey,
273 void **pValue,
274 void *plContext)
275 {
276 pkix_pl_HT_Elem *element = NULL;
277 pkix_pl_HT_Elem *prior = NULL;
278 PKIX_Boolean compResult;
279
280 PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Remove");
281 PKIX_NULLCHECK_FOUR(ht, key, pKey, pValue);
282
283 *pKey = NULL;
284 *pValue = NULL;
285
286 for (element = ht->buckets[hashCode%ht->size], prior = element;
287 (element != NULL);
288 prior = element, element = element->next) {
289
290 if (element->hashCode != hashCode){
291 /* no possibility of a match */
292 continue;
293 }
294
295 if (keyComp == NULL){
296 PKIX_CHECK(pkix_pl_KeyComparator_Default
297 ((PKIX_UInt32 *)key,
298 (PKIX_UInt32 *)(element->key),
299 &compResult,
300 plContext),
301 PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
302 } else {
303 PKIX_CHECK(keyComp
304 ((PKIX_PL_Object *)key,
305 (PKIX_PL_Object *)(element->key),
306 &compResult,
307 plContext),
308 PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
309 }
310
311 if ((element->hashCode == hashCode) &&
312 (compResult == PKIX_TRUE)){
313 if (element != prior) {
314 prior->next = element->next;
315 } else {
316 ht->buckets[hashCode%ht->size] = element->next;
317 }
318 *pKey = element->key;
319 *pValue = element->value;
320 element->key = NULL;
321 element->value = NULL;
322 element->next = NULL;
323 PKIX_FREE(element);
324 goto cleanup;
325 }
326 }
327
328 cleanup:
329
330 PKIX_RETURN(HASHTABLE);
331 }
332
333
334 /*
335 * FUNCTION: pkix_pl_HashTableLookup
336 * DESCRIPTION:
337 *
338 * Looks up object using the key pointed to by "key" and hashCode value
339 * equal to "hashCode" from the PrimHashtable pointed to by "ht", using the
340 * function pointed to by "keyComp" to compare keys, and stores the object's
341 * value at "pResult". Assumes "key" is a PKIX_UInt32 or a PKIX_PL_Object.
342 * This function sets "pResult" to NULL if the key is not in the hashtable.
343 *
344 * PARAMETERS:
345 * "ht"
346 * Address of PrimHashtable to lookup object from. Must be non-NULL.
347 * "key"
348 * Address of key for lookup. Typically a PKIX_UInt32 or PKIX_PL_Object.
349 * Must be non-NULL.
350 * "keyComp"
351 * Address of function used to determine if two keys are equal.
352 * If NULL, pkix_pl_KeyComparator_Default is used.
353 * "hashCode"
354 * Hashcode value of the key.
355 * "pResult"
356 * Address where value will be stored. Must be non-NULL.
357 * "plContext"
358 * Platform-specific context pointer.
359 * THREAD SAFETY:
360 * Conditionally Thread Safe
361 * (see Thread Safety Definitions in Programmer's Guide)
362 * RETURNS:
363 * Returns NULL if the function succeeds.
364 * Returns a Fatal Error if the function fails in an unrecoverable way.
365 */
366 PKIX_Error *
367 pkix_pl_PrimHashTable_Lookup(
368 pkix_pl_PrimHashTable *ht,
369 void *key,
370 PKIX_UInt32 hashCode,
371 PKIX_PL_EqualsCallback keyComp,
372 void **pResult,
373 void *plContext)
374 {
375 pkix_pl_HT_Elem *element = NULL;
376 PKIX_Boolean compResult = PKIX_FALSE;
377
378 PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Lookup");
379 PKIX_NULLCHECK_THREE(ht, key, pResult);
380
381 *pResult = NULL;
382
383 for (element = (ht->buckets)[hashCode%ht->size];
384 (element != NULL) && (*pResult == NULL);
385 element = element->next) {
386
387 if (element->hashCode != hashCode){
388 /* no possibility of a match */
389 continue;
390 }
391
392 if (keyComp == NULL){
393 PKIX_CHECK(pkix_pl_KeyComparator_Default
394 ((PKIX_UInt32 *)key,
395 (PKIX_UInt32 *)(element->key),
396 &compResult,
397 plContext),
398 PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
399 } else {
400 pkixErrorResult =
401 keyComp((PKIX_PL_Object *)key,
402 (PKIX_PL_Object *)(element->key),
403 &compResult,
404 plContext);
405 if (pkixErrorResult) {
406 pkixErrorClass = PKIX_FATAL_ERROR;
407 pkixErrorCode = PKIX_COULDNOTTESTWHETHERKEYSEQUAL;
408 goto cleanup;
409 }
410 }
411
412 if ((element->hashCode == hashCode) &&
413 (compResult == PKIX_TRUE)){
414 *pResult = element->value;
415 goto cleanup;
416 }
417 }
418
419 /* if we've reached here, specified key doesn't exist in hashtable */
420 *pResult = NULL;
421
422 cleanup:
423
424 PKIX_RETURN(HASHTABLE);
425 }
426
427 /*
428 * FUNCTION: pkix_pl_PrimHashTable_Destroy
429 *
430 * Destroys PrimHashTable pointed to by "ht".
431 *
432 * PARAMETERS:
433 * "ht"
434 * Address of PrimHashtable to free. Must be non-NULL.
435 * "plContext"
436 * Platform-specific context pointer.
437 * THREAD SAFETY:
438 * Not Thread Safe - assumes exclusive access to "ht"
439 * (see Thread Safety Definitions in Programmer's Guide)
440 * RETURNS
441 * Returns NULL if the function succeeds.
442 * Returns a HashTable Error if the function fails in a non-fatal way.
443 * Returns a Fatal Error if the function fails in an unrecoverable way.
444 */
445 PKIX_Error *
446 pkix_pl_PrimHashTable_Destroy(
447 pkix_pl_PrimHashTable *ht,
448 void *plContext)
449 {
450 pkix_pl_HT_Elem *element = NULL;
451 pkix_pl_HT_Elem *temp = NULL;
452 PKIX_UInt32 i;
453
454 PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Destroy");
455 PKIX_NULLCHECK_ONE(ht);
456
457 /* Free each element (list) */
458 for (i = 0; i < ht->size; i++) {
459 for (element = ht->buckets[i];
460 element != NULL;
461 element = temp) {
462 temp = element->next;
463 element->value = NULL;
464 element->key = NULL;
465 element->hashCode = 0;
466 element->next = NULL;
467 PKIX_FREE(element);
468 }
469 }
470
471 /* Free the pointer to the list array */
472 PKIX_FREE(ht->buckets);
473 ht->size = 0;
474
475 /* Free the table itself */
476 PKIX_FREE(ht);
477
478 PKIX_RETURN(HASHTABLE);
479 }
480
481 /*
482 * FUNCTION: pkix_pl_PrimHashTable_GetBucketSize
483 * DESCRIPTION:
484 *
485 * Retruns number of entries in the bucket the "hashCode" is designated in
486 * the hashtable "ht" in the address "pBucketSize".
487 *
488 * PARAMETERS:
489 * "ht"
490 * Address of PrimHashtable to get entries count. Must be non-NULL.
491 * "hashCode"
492 * Hashcode value of the key.
493 * "pBucketSize"
494 * Address that an PKIX_UInt32 is returned for number of entries in the
495 * bucket associated with the hashCode. Must be non-NULL.
496 * "plContext"
497 * Platform-specific context pointer.
498 * THREAD SAFETY:
499 * Not Thread Safe - assumes exclusive access to "ht"
500 * (see Thread Safety Definitions in Programmer's Guide)
501 * RETURNS:
502 * Returns NULL if the function succeeds.
503 * Returns a HashTable Error if the function fails in a non-fatal way.
504 * Returns a Fatal Error if the function fails in an unrecoverable way.
505 */
506 PKIX_Error *
507 pkix_pl_PrimHashTable_GetBucketSize(
508 pkix_pl_PrimHashTable *ht,
509 PKIX_UInt32 hashCode,
510 PKIX_UInt32 *pBucketSize,
511 void *plContext)
512 {
513 pkix_pl_HT_Elem **elemPtr = NULL;
514 pkix_pl_HT_Elem *element = NULL;
515 PKIX_UInt32 bucketSize = 0;
516
517 PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_GetBucketSize");
518 PKIX_NULLCHECK_TWO(ht, pBucketSize);
519
520 for (elemPtr = &((ht->buckets)[hashCode%ht->size]), element = *elemPtr;
521 element != NULL; elemPtr = &(element->next), element = *elemPtr) {
522 bucketSize++;
523 }
524
525 *pBucketSize = bucketSize;
526
527 PKIX_RETURN(HASHTABLE);
528 }
529
530 /*
531 * FUNCTION: pkix_pl_PrimHashTable_RemoveFIFO
532 * DESCRIPTION:
533 *
534 * Remove the first entry in the bucket the "hashCode" is designated in
535 * the hashtable "ht". Since new entry is added at end of the link list
536 * the first one is the oldest (FI) therefore removed first (FO).
537 *
538 * PARAMETERS:
539 * "ht"
540 * Address of PrimHashtable to get entries count. Must be non-NULL.
541 * "hashCode"
542 * Hashcode value of the key.
543 * "pKey"
544 * Address of key of the entry deleted. Must be non-NULL.
545 * "pValue"
546 * Address of Value of the entry deleted. Must be non-NULL.
547 * "plContext"
548 * Platform-specific context pointer.
549 * THREAD SAFETY:
550 * Not Thread Safe - assumes exclusive access to "ht"
551 * (see Thread Safety Definitions in Programmer's Guide)
552 * RETURNS:
553 * Returns NULL if the function succeeds.
554 * Returns a HashTable Error if the function fails in a non-fatal way.
555 * Returns a Fatal Error if the function fails in an unrecoverable way.
556 */
557 PKIX_Error *
558 pkix_pl_PrimHashTable_RemoveFIFO(
559 pkix_pl_PrimHashTable *ht,
560 PKIX_UInt32 hashCode,
561 void **pKey,
562 void **pValue,
563 void *plContext)
564 {
565 pkix_pl_HT_Elem *element = NULL;
566
567 PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Remove");
568 PKIX_NULLCHECK_THREE(ht, pKey, pValue);
569
570 element = (ht->buckets)[hashCode%ht->size];
571
572 if (element != NULL) {
573
574 *pKey = element->key;
575 *pValue = element->value;
576 ht->buckets[hashCode%ht->size] = element->next;
577 element->key = NULL;
578 element->value = NULL;
579 element->next = NULL;
580 PKIX_FREE(element);
581 }
582
583 PKIX_RETURN(HASHTABLE);
584 }
OLDNEW
« no previous file with comments | « nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h ('k') | nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698