21 namespace perfect_hash {
26 const auto empty = -1;
28 for (
size_t e = 0; e < entry_count; ++e, ++ptr) {
39 s.insert({std::move(key), std::move(payload)});
44 const int32_t*
const ptr3,
45 const int32_t*
const ptr4,
50 for (
size_t e = 0; e < entry_count; ++e, ++ptr) {
58 int32_t offset = ptr2[e];
60 int32_t count = ptr3[e];
63 for (
size_t j = 0; j < static_cast<size_t>(count); ++j) {
64 payload.insert(ptr4[offset + j]);
67 s.insert({std::move(key), std::move(payload)});
73 namespace keyed_hash {
78 size_t key_component_count,
80 auto empty = get_empty_key<T>();
81 auto ptr =
reinterpret_cast<const T*
>(ptr1);
82 for (
size_t e = 0; e < entry_count; ++e, ptr += key_component_count) {
87 std::vector<int64_t> key;
89 for (; j < key_component_count - 1; ++j) {
90 key.push_back(ptr[j]);
93 std::set<int32_t> payload;
94 payload.insert(ptr[j]);
96 s.insert({std::move(key), std::move(payload)});
100 template <
typename T>
102 const int32_t*
const ptr2,
103 const int32_t*
const ptr3,
104 const int32_t*
const ptr4,
106 size_t key_component_count,
108 auto empty = get_empty_key<T>();
109 auto ptr =
reinterpret_cast<const T*
>(ptr1);
110 for (
size_t e = 0; e < entry_count; ++e, ptr += key_component_count) {
115 std::vector<int64_t> key;
117 for (; j < key_component_count - 1; ++j) {
118 key.push_back(ptr[j]);
121 int32_t offset = ptr2[e];
123 int32_t count = ptr3[e];
126 for (
size_t j = 0; j < static_cast<size_t>(count); ++j) {
127 payload.insert(ptr4[offset + j]);
130 s.insert({std::move(key), std::move(payload)});
140 size_t key_component_count,
141 size_t key_component_width,
147 size_t buffer_size) {
155 bool have_keys = ptr2 > ptr1;
156 bool have_offsets = ptr3 > ptr2;
157 bool have_counts = ptr4 > ptr3;
158 bool have_payloads = (ptr1 + buffer_size) > ptr4;
160 auto i32ptr2 =
reinterpret_cast<const int32_t*
>(ptr2);
161 auto i32ptr3 =
reinterpret_cast<const int32_t*
>(ptr3);
162 auto i32ptr4 =
reinterpret_cast<const int32_t*
>(ptr4);
165 CHECK(key_component_width == 8 || key_component_width == 4);
166 if (key_component_width == 8) {
167 if (!have_offsets && !have_counts) {
168 keyed_hash::to_set_one_to_one<int64_t>(ptr1, entry_count, key_component_count, s);
170 keyed_hash::to_set_one_to_many<int64_t>(
171 ptr1, i32ptr2, i32ptr3, i32ptr4, entry_count, key_component_count, s);
173 }
else if (key_component_width == 4) {
174 if (!have_offsets && !have_counts) {
175 keyed_hash::to_set_one_to_one<int32_t>(ptr1, entry_count, key_component_count, s);
177 keyed_hash::to_set_one_to_many<int32_t>(
178 ptr1, i32ptr2, i32ptr3, i32ptr4, entry_count, key_component_count, s);
182 if (!have_offsets && !have_counts && have_payloads) {
194 template <
typename T>
197 size_t key_component_count,
200 auto empty = get_empty_key<T>();
201 auto ptr =
reinterpret_cast<const T*
>(ptr1);
202 for (
size_t e = 0; e < entry_count; ++e, ptr += key_component_count) {
206 if (*ptr == empty && !raw) {
208 }
else if (*ptr == empty - 1 && !raw) {
212 for (
size_t j = 0; j < key_component_count; ++j) {
227 const std::string&
type,
228 const std::string& layout_type,
229 size_t key_component_count,
230 size_t key_component_width,
243 CHECK(ptr4 <= ptr1 + buffer_size);
245 bool have_keys = ptr2 > ptr1;
246 bool have_offsets = ptr3 > ptr2;
247 bool have_counts = ptr4 > ptr3;
248 bool have_payloads = (ptr1 + buffer_size) > ptr4;
252 if (!have_offsets && !have_counts) {
254 }
else if (have_offsets && have_counts) {
262 CHECK(key_component_width == 8 || key_component_width == 4);
269 if (key_component_width == 8) {
270 inner_to_string<int64_t>(ptr1, entry_count, key_component_count, raw, txt);
271 }
else if (key_component_width == 4) {
272 inner_to_string<int32_t>(ptr1, entry_count, key_component_count, raw, txt);
283 auto i32ptr2 =
reinterpret_cast<const int32_t*
>(ptr2);
284 auto i32ptr3 =
reinterpret_cast<const int32_t*
>(ptr3);
285 for (
size_t i = 0; &i32ptr2[i] < i32ptr3; ++i) {
289 if (i32ptr2[i] == -1 && !raw) {
304 auto i32ptr3 =
reinterpret_cast<const int32_t*
>(ptr3);
305 auto i32ptr4 =
reinterpret_cast<const int32_t*
>(ptr4);
306 for (
size_t i = 0; &i32ptr3[i] < i32ptr4; ++i) {
310 if (i32ptr3[i] == 0 && !raw) {
323 txt +=
"| payloads ";
325 auto i32ptr4 =
reinterpret_cast<const int32_t*
>(ptr4);
326 auto i32ptr5 =
reinterpret_cast<const int32_t*
>(ptr1 + buffer_size);
327 for (
size_t i = 0; &i32ptr4[i] < i32ptr5; ++i) {
331 if (i32ptr4[i] == -1 && !raw) {
void inner_to_string(const int8_t *ptr1, size_t entry_count, size_t key_component_count, bool raw, std::string &txt)
std::set< DecodedJoinHashBufferEntry > DecodedJoinHashBufferSet
static std::string toString(const std::string &type, const std::string &layout_type, size_t key_component_count, size_t key_component_width, size_t entry_count, const int8_t *ptr1, const int8_t *ptr2, const int8_t *ptr3, const int8_t *ptr4, size_t buffer_size, bool raw=false)
Decode hash table into a human-readable string.
std::set< int32_t > payload
static DecodedJoinHashBufferSet toSet(size_t key_component_count, size_t key_component_width, size_t entry_count, const int8_t *ptr1, const int8_t *ptr2, const int8_t *ptr3, const int8_t *ptr4, size_t buffer_size)
Decode hash table into a std::set for easy inspection and validation.
void to_set_one_to_many(const int32_t *const ptr2, const int32_t *const ptr3, const int32_t *const ptr4, size_t entry_count, DecodedJoinHashBufferSet &s)
std::vector< int64_t > key
void to_set_one_to_one(const int32_t *const ptr4, size_t entry_count, DecodedJoinHashBufferSet &s)