access_plhash.cpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /*
  13. This file contains a function which augments the standard nspr PL_HashTable
  14. api. The problem is that the hash table lookup function in the standard NSPR
  15. actually modifies the hash table being searched, which means that it cannot be
  16. used with read locks in a multi threaded environment. This function is a
  17. lookup function which is guaranteed not to modify the hash table passed in,
  18. so that it can be used with read locks.
  19. */
  20. #include "plhash.h"
  21. /* prototypes */
  22. NSPR_BEGIN_EXTERN_C
  23. PR_IMPLEMENT(void *)
  24. ACL_HashTableLookup_const(PLHashTable *ht, const void *key);
  25. NSPR_END_EXTERN_C
  26. /*
  27. ** Multiplicative hash, from Knuth 6.4.
  28. */
  29. #define GOLDEN_RATIO 0x9E3779B9U
  30. PR_IMPLEMENT(PLHashEntry **)
  31. ACL_HashTableRawLookup_const(PLHashTable *ht, PLHashNumber keyHash, const void *key)
  32. {
  33. PLHashEntry *he, **hep;
  34. PLHashNumber h;
  35. #ifdef HASHMETER
  36. ht->nlookups++;
  37. #endif
  38. h = keyHash * GOLDEN_RATIO;
  39. h >>= ht->shift;
  40. hep = &ht->buckets[h];
  41. while ((he = *hep) != 0) {
  42. if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) {
  43. return hep;
  44. }
  45. hep = &he->next;
  46. #ifdef HASHMETER
  47. ht->nsteps++;
  48. #endif
  49. }
  50. return hep;
  51. }
  52. PR_IMPLEMENT(void *)
  53. ACL_HashTableLookup_const(PLHashTable *ht, const void *key)
  54. {
  55. PLHashNumber keyHash;
  56. PLHashEntry *he, **hep;
  57. keyHash = (*ht->keyHash)(key);
  58. hep = ACL_HashTableRawLookup_const(ht, keyHash, key);
  59. if ((he = *hep) != 0) {
  60. return he->value;
  61. }
  62. return 0;
  63. }