hash_table.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "hash_table.hpp"
  2. #include <new>
  3. #include <thread>
  4. #include <cstdint>
  5. namespace xrcu
  6. {
  7. namespace detail
  8. {
  9. inline ht_vector* ht_vector_make (size_t n)
  10. {
  11. void *p = ::operator new (sizeof (ht_vector) + n * sizeof (uintptr_t));
  12. return (new (p) ht_vector ((uintptr_t *)((char *)p + sizeof (ht_vector))));
  13. }
  14. void ht_vector::safe_destroy ()
  15. {
  16. ::operator delete (this);
  17. }
  18. static const size_t PRIMES[] =
  19. {
  20. 0xb, 0x25, 0x71, 0x15b, 0x419, 0xc4d, 0x24f5, 0x6ee3, 0x14cb3, 0x3e61d,
  21. 0xbb259, 0x23170f, 0x694531, 0x13bcf95, 0x3b36ec3, 0xb1a4c4b, 0x214ee4e3,
  22. 0x63ecaead
  23. #if SIZE_MAX > 0xffffffffu
  24. , 0x12bc60c09ull, 0x38352241dull, 0xa89f66c5bull, 0x1f9de34513ull,
  25. 0x5ed9a9cf3bull, 0x11c8cfd6db5ull, 0x355a6f84921ull, 0xa00f4e8db65ull,
  26. 0x1e02deba9233ull, 0x5a089c2fb69bull, 0x10e19d48f23d3ull, 0x32a4d7dad6b7dull,
  27. 0x97ee879084279ull, 0x1c7cb96b18c76dull, 0x55762c414a564bull,
  28. 0x1006284c3df02e3ull, 0x301278e4b9d08abull, 0x90376aae2d71a05ull,
  29. 0x1b0a6400a8854e11ull, 0x511f2c01f98fea35ull
  30. #endif
  31. };
  32. size_t find_hsize (size_t size, float mvr, size_t& pidx)
  33. {
  34. intptr_t i1 = 0, i2 = sizeof (PRIMES) / sizeof (PRIMES[0]);
  35. while (i1 < i2)
  36. {
  37. intptr_t step = (i1 + i2) >> 1;
  38. if (PRIMES[step] < size)
  39. i1 = step + 1;
  40. else
  41. i2 = step;
  42. }
  43. pidx = i1;
  44. return ((size_t)(PRIMES[i1] * mvr));
  45. }
  46. ht_vector* make_htvec (size_t pidx, uintptr_t key, uintptr_t val)
  47. {
  48. size_t entries = PRIMES[pidx], tsize = table_idx (entries);
  49. #ifdef XRCU_HAVE_XATOMIC_DCAS
  50. auto ret = ht_vector_make (tsize + 1);
  51. // Ensure correct alignment for double-width CAS.
  52. if ((uintptr_t)ret->data % (2 * sizeof (uintptr_t)) != 0)
  53. ++ret->data;
  54. #else
  55. auto ret = ht_vector_make (tsize);
  56. #endif
  57. for (size_t i = 0; i < tsize; i += 2)
  58. ret->data[i] = key, ret->data[i + 1] = val;
  59. ret->entries = entries;
  60. ret->pidx = pidx;
  61. return (ret);
  62. }
  63. } // namespace detail
  64. } // namespace xrcu