RPNX::DataStructures
Header-only C++ data structures and supporting utilities.
Loading...
Searching...
No Matches
hadix_map.hpp
1// Copyright (c) 2026 Ryan P. Nicholl <rnicholl@protonmail.com>
2
3#ifndef RPNXHADIX_HADIX_HPP
4#define RPNXHADIX_HADIX_HPP
5
6#error "not implemented"
7#include "segmented_dynar.hpp"
8
9#include <algorithm>
10#include <array>
11#include <utility>
12
13namespace rpnx
14{
26 template < typename K, typename V, typename Hash = std::hash< K >, typename KeyEqual = std::equal_to< K >, typename Alloc = std::allocator< std::pair< const K, V > > >
28 {
29 enum class color : std::uint8_t
30 {
31 red,
32 black
33 };
34
35 struct node
36 {
37 std::pair<const K, V> item;
38 color m_color;
39 node * m_left;
40 node * m_right;
41 };
42
43 using hash_type = std::uint64_t;
44
45 static constexpr std::size_t hash_per_bucket = std::max< std::size_t >(4, std::max< std::size_t >(std::hardware_destructive_interference_size, std::hardware_constructive_interference_size) / sizeof(hash_type));
46
47 struct alignas(std::hardware_destructive_interference_size) bucket
48 {
49 std::array< hash_type, hash_per_bucket > bucket_hashes;
50 std::array< node*, hash_per_bucket > bucket_nodes;
51 node * m_overflow;
52 };
53
55 std::size_t m_size;
56
57 static hash_type reverse_bits(hash_type i)
58 {
59 i = ((i & 0x5555555555555555) << 1) | ((i & 0xAAAAAAAAAAAAAAAA) >> 1);
60 i = ((i & 0x3333333333333333) << 2) | ((i & 0xCCCCCCCCCCCCCCCC) >> 2);
61 i = ((i & 0x0F0F0F0F0F0F0F0F) << 4) | ((i & 0xF0F0F0F0F0F0F0F0) >> 4);
62 i = ((i & 0x00FF00FF00FF00FF) << 8) | ((i & 0xFF00FF00FF00FF00) >> 8);
63 i = ((i & 0x0000FFFF0000FFFF) << 16) | ((i & 0xFFFF0000FFFF0000) >> 16);
64 i = (i << 32) | (i >> 32);
65 return i;
66 }
67
68 std::size_t bucket_index(hash_type h)
69 {
70 auto index = reverse_bits(h);
71
72 // 2. Determine the bit-mask based on current table size
73 // std::bit_width(size - 1) gives the number of bits to cover the range
74 auto size = m_buckets.size();
75 int bits = std::bit_width(size - 1);
76
77 // 3. Create the mask (handle 64-bit edge case)
78 hash_type mask = (bits >= (sizeof(hash_type) * 8)) ? ~hash_type(0) : (hash_type(1) << bits) - 1;
79
80 auto result = index & mask;
81
82 // 4. The "Fold" Logic:
83 // If the index is out of bounds, it must be in the range [size, 2^bits - 1].
84 // Stripping the highest bit guaranteed to fit it in the range [0, size - 1].
85 if (result >= size)
86 {
87 result &= (mask >> 1);
88 }
89
90 return result;
91 }
92 };
93} // namespace rpnx
94
95#endif // RPNXHADIX_HADIX_HPP
Reserved prototype for a hadix map.
Definition hadix_map.hpp:28
A generic result class that can hold either a value or an exception.
Definition result.hpp:21
Dynamic array backed by exponentially sized stable segments.
Definition segmented_dynar.hpp:45
Containers, iterator adapters, callable wrappers, and value utilities.
Definition annex.hpp:14