mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
WasmAlgo.hpp
Go to the documentation of this file.
1#pragma once
2
5#include <optional>
6
7// must be included after Binaryen due to conflicts, e.g. with `::wasm::Throw`
9
10
11namespace m {
12
13namespace wasm {
14
15// forward declarations
16template<bool IsGlobal> struct ChainedHashTable;
17template<bool IsGlobal, bool ValueInPlace> struct OpenAddressingHashTable;
18struct ProbingStrategy;
19
20/*======================================================================================================================
21 * sorting
22 *====================================================================================================================*/
23
27template<bool CmpPredicated, bool IsGlobal>
28void quicksort(Buffer<IsGlobal> &buffer, const std::vector<SortingOperator::order_type> &order);
29
30
31/*======================================================================================================================
32 * hashing
33 *====================================================================================================================*/
34
35/*----- bit mix functions --------------------------------------------------------------------------------------------*/
36
38U64x1 murmur3_bit_mix(U64x1 bits);
39
40
41/*----- hash functions -----------------------------------------------------------------------------------------------*/
42
44U64x1 fnv_1a(Ptr<U8x1> bytes, U32x1 num_bytes);
46U64x1 str_hash(NChar str);
49U64x1 murmur3_64a_hash(std::vector<std::pair<const Type*, SQL_t>> values);
50
51
52/*----- hash tables --------------------------------------------------------------------------------------------------*/
53
56{
57 using index_t = std::size_t;
58 using offset_t = int32_t;
59 using size_t = uint32_t;
60
61 // forward declaration
62 template<bool IsConst> struct the_entry;
63
65 template<sql_type T, bool IsConst>
67
68 template<sql_type T, bool IsConst>
69 requires (not std::same_as<T, NChar>) and (T::num_simd_lanes == 1)
71 {
72 friend struct the_entry<false>;
73 friend struct the_entry<true>;
74
76
77 private:
79 std::optional<Ptr<U8x1>> is_null_byte_;
80 std::optional<U8x1> is_null_mask_;
81
82 explicit the_reference(Ptr<value_t> value, std::optional<Ptr<U8x1>> is_null_byte, std::optional<U8x1> is_null_mask)
83 : value_(value)
84 , is_null_byte_(std::move(is_null_byte))
85 , is_null_mask_(std::move(is_null_mask))
86 {
88 "either both or none of NULL byte and NULL mask must be specified");
89 }
90 explicit the_reference(Ptr<value_t> value, Ptr<U8x1> is_null_byte, U8x1 is_null_mask)
91 : value_(value)
92 , is_null_byte_(is_null_byte)
93 , is_null_mask_(is_null_mask)
94 { }
95
96 public:
98 explicit the_reference(Ptr<value_t> value, Ptr<void> null_bitmap, uint8_t null_bit_offset)
99 : value_(value)
100 , is_null_byte_((null_bitmap + (null_bit_offset / 8)).to<uint8_t*>())
101 , is_null_mask_(1U << (null_bit_offset % 8))
102 { }
103
105 void discard() {
106 value_.discard();
107 if (is_null_byte_) {
108 is_null_byte_->discard();
109 is_null_mask_->discard();
110 }
111 }
114 if (is_null_byte_)
115 return the_reference(value_.clone(), is_null_byte_->clone(), is_null_mask_->clone());
116 else
117 return the_reference(value_.clone());
118 }
119
121 void operator=(T _value) requires (not IsConst) {
122 M_insist(bool(is_null_byte_) == _value.can_be_null(), "value of non-nullable entry must not be nullable");
123 if (is_null_byte_) {
124 auto [value, is_null] = _value.split();
125 *value_ = value;
127 } else {
128 *value_ = _value.insist_not_null();
129 }
130 }
132 void set_value(value_t value) requires (not IsConst) {
133 *value_ = value;
134 if (is_null_byte_) {
135 is_null_byte_->discard();
136 is_null_mask_->discard();
137 }
138 }
139
141 void set_null_bit(Boolx1 is_null) requires (not IsConst) {
142 value_.discard();
143 M_insist(bool(is_null_byte_));
144 M_insist(bool(is_null_mask_));
146 }
148 void set_null() requires (not IsConst) {
149 value_.discard();
150 M_insist(bool(is_null_byte_));
151 M_insist(bool(is_null_mask_));
153 }
155 void set_not_null() requires (not IsConst) {
156 value_.discard();
157 M_insist(bool(is_null_byte_));
158 M_insist(bool(is_null_mask_));
160 }
161
163 Boolx1 operator==(T _value) {
164 auto [value, is_null] = _value.split();
165 if (is_null_byte_) {
166 auto is_null_ = (**is_null_byte_ bitand *is_null_mask_).template to<bool>();
167 auto equal_nulls = is_null_.clone() == is_null;
168 return equal_nulls and (is_null_ or *value_ == value);
169 } else {
170 return not is_null and *value_ == value;
171 }
172 }
173
175 operator T() {
176 if (is_null_byte_)
177 return T(*value_, (**is_null_byte_ bitand *is_null_mask_).template to<bool>());
178 else
179 return T(*value_);
180 }
181
183 friend the_reference Select(Boolx1 cond, the_reference tru, the_reference fals) {
184 M_insist(bool(tru.is_null_byte_) == bool(fals.is_null_byte_), "null byte mismatch");
185 M_insist(bool(tru.is_null_mask_) == bool(fals.is_null_mask_), "null mask mismatch");
186 if (tru.is_null_byte_) {
188 /* value_= */ Select(cond.clone(), tru.value_, fals.value_),
189 /* is_null_byte_= */ Select(cond.clone(), *tru.is_null_byte_, *fals.is_null_byte_),
190 /* is_null_mask_= */ Select(cond.clone(), *tru.is_null_mask_, *fals.is_null_mask_)
191 );
192 cond.discard();
193 return r;
194 } else {
195 return the_reference(Select(cond, tru.value_, fals.value_));
196 }
197 }
198 };
199
200 template<bool IsConst>
202 {
203 friend struct the_entry<false>;
204 friend struct the_entry<true>;
205
206 private:
208 std::optional<Ptr<U8x1>> is_null_byte_;
209 std::optional<U8x1> is_null_mask_;
210
211 explicit the_reference(NChar addr, std::optional<Ptr<U8x1>> is_null_byte, std::optional<U8x1> is_null_mask)
212 : addr_(addr)
213 , is_null_byte_(std::move(is_null_byte))
214 , is_null_mask_(std::move(is_null_mask))
215 {
216 M_insist(addr.can_be_null() == bool(is_null_byte_), "nullable entry must have a NULL bit");
217 M_insist(bool(is_null_byte_) == bool(is_null_mask_),
218 "either both or none of NULL byte and NULL mask must be specified");
219 }
220 explicit the_reference(NChar addr, Ptr<U8x1> is_null_byte, U8x1 is_null_mask)
221 : addr_(addr)
222 , is_null_byte_(is_null_byte)
223 , is_null_mask_(is_null_mask)
224 {
225 M_insist(addr.can_be_null(), "entry with NULL bit must be nullable");
226 }
227
228 public:
229 explicit the_reference(NChar addr)
230 : addr_(addr)
231 {
232 M_insist(not addr.can_be_null(), "entry without NULL bit must be nullable"); \
233 }
234 explicit the_reference(NChar addr, Ptr<void> null_bitmap, uint8_t null_bit_offset)
235 : addr_(addr)
236 , is_null_byte_((null_bitmap + (null_bit_offset / 8)).to<uint8_t*>())
237 , is_null_mask_(1U << (null_bit_offset % 8))
238 {
239 M_insist(addr.can_be_null(), "entry with NULL bit must be nullable");
240 }
241
243 void discard() {
244 addr_.discard();
245 if (addr_.can_be_null()) {
246 is_null_byte_->discard();
247 is_null_mask_->discard();
248 }
249 }
252 if (addr_.can_be_null())
253 return the_reference(addr_.clone(), is_null_byte_->clone(), is_null_mask_->clone());
254 else
255 return the_reference(addr_.clone());
256 }
257
259 void operator=(NChar addr) requires (not IsConst) {
260 M_insist(addr_.length() == addr.length() and
261 addr_.guarantees_terminating_nul() == addr.guarantees_terminating_nul(),
262 "type mismatch");
263 if (addr_.can_be_null()) {
264 IF (not addr.clone().is_null()) {
265 strncpy(addr_, addr.clone(), U32x1(addr.size_in_bytes())).discard();
266 };
267 setbit(*is_null_byte_, addr.is_null(), *is_null_mask_);
268 } else {
269 Wasm_insist(addr.clone().not_null(), "value of non-nullable entry must not be nullable");
270 strncpy(addr_, addr, U32x1(addr.size_in_bytes())).discard();
271 }
272 }
274 void set_value(NChar addr) requires (not IsConst) {
275 M_insist(addr_.length() == addr.length() and
276 addr_.guarantees_terminating_nul() == addr.guarantees_terminating_nul(),
277 "type mismatch");
278 strncpy(addr_, addr, U32x1(addr.size_in_bytes())).discard();
279 if (addr_.can_be_null()) {
280 is_null_byte_->discard();
281 is_null_mask_->discard();
282 }
283 }
285 void set_null_bit(Boolx1 is_null) requires (not IsConst) {
286 addr_.discard();
287 M_insist(bool(is_null_byte_));
288 M_insist(bool(is_null_mask_));
290 }
292 void set_null() requires (not IsConst) {
293 addr_.discard();
294 M_insist(bool(is_null_byte_));
295 M_insist(bool(is_null_mask_));
297 }
299 void set_not_null() requires (not IsConst) {
300 addr_.discard();
301 M_insist(bool(is_null_byte_));
302 M_insist(bool(is_null_mask_));
304 }
305
307 Boolx1 operator==(NChar _addr) {
308 M_insist(addr_.length() == _addr.length() and
310 "type mismatch");
311 auto [addr, is_nullptr] = _addr.split();
312 _Boolx1 _equal_addrs = strncmp(addr_, NChar(addr, _addr.can_be_null(), addr_.length(),
314 U32x1(addr_.length()), EQ);
315 auto [equal_addrs_val, equal_addrs_is_null] = _equal_addrs.split();
316 equal_addrs_is_null.discard(); // use potentially-null value but it is overruled if it is invalid, i.e. NULL
317 if (addr_.can_be_null()) {
318 auto is_nullptr_ = (**is_null_byte_ bitand *is_null_mask_).template to<bool>();
319 auto equal_nulls = is_nullptr_.clone() == is_nullptr;
320 return equal_nulls and (is_nullptr_ or equal_addrs_val);
321 } else {
322 return not is_nullptr and equal_addrs_val;
323 }
324 }
325
327 operator NChar() {
328 if (addr_.can_be_null()) {
329 Boolx1 is_null = (**is_null_byte_ bitand *is_null_mask_).template to<bool>();
330 return NChar(Select(is_null, Ptr<Charx1>::Nullptr(), addr_.val()), /* can_be_null= */ true,
331 addr_.length(), addr_.guarantees_terminating_nul());
332 } else {
333 return addr_;
334 }
335 }
336
338 friend the_reference Select(Boolx1 cond, the_reference tru, the_reference fals) {
339 M_insist(tru.addr_.can_be_null() == fals.addr_.can_be_null(), "nullable mismatch");
340 M_insist(tru.addr_.length() == fals.addr_.length() and
341 tru.addr_.guarantees_terminating_nul() == fals.addr_.guarantees_terminating_nul(),
342 "type mismatch");
343 M_insist(bool(tru.is_null_byte_) == bool(fals.is_null_byte_), "null byte mismatch");
344 M_insist(bool(tru.is_null_mask_) == bool(fals.is_null_mask_), "null mask mismatch");
345 if (tru.addr_.can_be_null()) {
347 /* addr_= */ NChar(Select(cond.clone(), tru.addr_, fals.addr_), /* can_be_null= */ true,
348 tru.addr_.length(), tru.addr_.guarantees_terminating_nul()),
349 /* is_null_byte_= */ Select(cond.clone(), *tru.is_null_byte_, *fals.is_null_byte_),
350 /* is_null_mask_= */ Select(cond.clone(), *tru.is_null_mask_, *fals.is_null_mask_)
351 );
352 cond.discard();
353 return r;
354 } else {
355 return the_reference(NChar(Select(cond, tru.addr_, fals.addr_), /* can_be_null= */ false,
356 tru.addr_.length(), tru.addr_.guarantees_terminating_nul()));
357 }
358 }
359 };
360
361 template<sql_type T>
363 template<sql_type T>
365
367 template<bool IsConst>
369 {
370 friend struct HashTable;
371
372 using value_t = std::variant<
373 std::monostate
374#define ADD_TYPE(TYPE) , the_reference<TYPE, IsConst>
376#undef ADD_TYPE
377 >;
378
379 private:
381 static void discard(value_t &ref) {
382 std::visit(overloaded {
383 [](auto &r) { r.discard(); },
384 [](std::monostate) { M_unreachable("invalid variant"); },
385 }, ref);
386 }
387
388 private:
391 std::unordered_multimap<Schema::Identifier, value_t> refs_;
392
393 public:
394 the_entry() = default;
395 the_entry(const the_entry&) = delete;
396 the_entry(the_entry&&) = default;
397
398 private:
400 the_entry(std::unordered_multimap<Schema::Identifier, typename the_entry<not IsConst>::value_t> refs) {
401 refs_.reserve(refs.size());
402 for (auto &p : refs) {
403 std::visit(overloaded {
404 [&]<typename T>(the_reference<T, not IsConst> &r) {
406 r.value_, std::move(r.is_null_byte_), std::move(r.is_null_mask_)
407 );
408 refs_.emplace(std::move(p.first), std::move(ref));
409 },
412 r.addr_, std::move(r.is_null_byte_), std::move(r.is_null_mask_)
413 );
414 refs_.emplace(std::move(p.first), std::move(ref));
415 },
416 [](std::monostate) { M_unreachable("invalid variant"); },
417 }, p.second);
418 }
419 }
420
421 public:
423 for (auto &p : refs_)
424 discard(p.second);
425 }
426
428 operator the_entry<true>() requires (not IsConst) { return the_entry<true>(std::move(refs_)); }
429
431 bool empty() const { return refs_.empty(); }
432
434 bool has(const Schema::Identifier &id) const { return refs_.contains(id); }
435
437 template<sql_type T>
439 refs_.emplace(std::move(id), std::forward<the_reference<T, IsConst>>(ref));
440 }
441
444 auto it = refs_.find(id);
445 M_insist(it != refs_.end(), "identifier not found");
446 auto nh = refs_.extract(it);
447 return std::move(nh.mapped());
448 }
450 template<sql_type T>
452 using type = the_reference<T, IsConst>;
453 M_insist(refs_.count(id) <= 1, "duplicate identifier, lookup ambiguous");
454 auto it = refs_.find(id);
455 M_insist(it != refs_.end(), "identifier not found");
456 auto nh = refs_.extract(it);
457 M_insist(std::holds_alternative<type>(nh.mapped()));
458 return std::move(*std::get_if<type>(&nh.mapped()));
459 }
460
462 value_t get(const Schema::Identifier &id) const {
463 M_insist(refs_.count(id) <= 1, "duplicate identifier, lookup ambiguous");
464 auto it = refs_.find(id);
465 M_insist(it != refs_.end(), "identifier not found");
466 return std::visit(overloaded {
467 [](auto &r) -> value_t { return r.clone(); },
468 [](std::monostate) -> value_t { M_unreachable("invalid reference"); },
469 }, it->second);
470 }
472 template<sql_type T>
473 the_reference<T, IsConst> get(const Schema::Identifier &id) const {
474 using type = the_reference<T, IsConst>;
475 M_insist(refs_.count(id) <= 1, "duplicate identifier, lookup ambiguous");
476 auto it = refs_.find(id);
477 M_insist(it != refs_.end(), "identifier not found");
478 M_insist(std::holds_alternative<type>(it->second));
479 return std::get_if<type>(&it->second)->clone();
480 }
481 };
482
485
486 using callback_t = std::function<void(const_entry_t)>;
487 using hint_t = std::optional<Ptr<void>>;
488
489 protected:
491 static std::vector<SQL_t> clone(const std::vector<SQL_t> &values) {
492 std::vector<SQL_t> cpy;
493 cpy.reserve(values.size());
494 for (auto &value : values) {
495 std::visit(overloaded {
496 [&](auto &v) { cpy.push_back(v.clone()); },
497 [](std::monostate) { M_unreachable("invalid variant"); },
498 }, value);
499 }
500 return cpy;
501 }
502
503 protected:
504 std::reference_wrapper<const Schema> schema_;
505 std::vector<index_t> key_indices_;
506 std::vector<index_t> value_indices_;
507
508 public:
509 HashTable() = delete;
510
512 HashTable(const Schema &schema, std::vector<index_t> key_indices)
513 : schema_(std::cref(schema))
514 , key_indices_(std::move(key_indices))
515 {
516 M_insist(schema.num_entries() != 0, "hash table schema must not be empty");
517 M_insist(not key_indices_.empty(), "must specify a key");
518
519 /*----- Compute `value_indices_` as complement of `key_indices_`. -----*/
520 for (index_t i = 0; i != schema.num_entries(); ++i) {
521 if (contains(key_indices_, i)) continue;
522 value_indices_.push_back(i);
523 }
524 }
525
526 HashTable(const HashTable&) = delete;
527 HashTable(HashTable&&) = default;
528
529 virtual ~HashTable() { }
530
531 const Schema & schema() const { return schema_; }
532
535 virtual void setup() = 0;
538 virtual void teardown() = 0;
539
542 virtual void set_high_watermark(double percentage) = 0;
543
545 virtual void clear() = 0;
546
548 virtual Ptr<void> compute_bucket(std::vector<SQL_t> key) const = 0;
549
554 virtual entry_t emplace(std::vector<SQL_t> key) = 0;
560 virtual std::pair<entry_t, Boolx1> try_emplace(std::vector<SQL_t> key) = 0;
561
567 virtual std::pair<entry_t, Boolx1> find(std::vector<SQL_t> key, hint_t bucket_hint = hint_t()) = 0;
573 std::pair<const_entry_t, Boolx1> find(std::vector<SQL_t> key, hint_t bucket_hint = hint_t()) const {
574 return const_cast<HashTable*>(this)->find(std::move(key), std::move(bucket_hint));
575 }
576
579 virtual void for_each(callback_t Pipeline) const = 0;
585 virtual void for_each_in_equal_range(std::vector<SQL_t> key, callback_t Pipeline, bool predicated = false,
586 hint_t bucket_hint = hint_t()) const = 0;
587
591 virtual entry_t dummy_entry() = 0;
592
593 protected:
598 std::pair<size_t, size_t> set_byte_offsets(std::vector<offset_t> &offsets_in_bytes,
599 const std::vector<const Type*> &types,
600 offset_t initial_offset_in_bytes = 0,
601 offset_t initial_max_alignment_in_bytes = 1);
602};
603
604
605/*----- chained hash tables ------------------------------------------------------------------------------------------*/
606
607template<bool IsGlobal>
609
610template<>
612
613template<>
615{
616 friend struct ChainedHashTable<true>;
617
622};
623
624template<bool IsGlobal>
626{
627 private:
629 template<typename T>
630 using var_t = std::conditional_t<IsGlobal, Global<T>, Var<T>>;
631
634 std::vector<HashTable::offset_t> entry_offsets_in_bytes_;
638
639 std::optional<Var<Ptr<void>>> address_;
641 std::optional<Var<U32x1>> mask_;
642 std::optional<Var<U32x1>> num_entries_;
645 std::optional<Var<U32x1>> high_watermark_absolute_;
649 std::optional<FunctionProxy<void(void)>> rehash_;
650 std::vector<std::pair<Ptr<void>, U32x1>> dummy_allocations_;
651 std::optional<var_t<Ptr<void>>> predication_dummy_;
652
653 public:
657 ChainedHashTable(const Schema &schema, std::vector<HashTable::index_t> key_indices, uint32_t initial_capacity);
658
660
662
663 private:
665 Ptr<void> begin() const { M_insist(bool(address_), "must call `setup()` before"); return *address_; }
667 Ptr<void> end() const { return begin() + size_in_bytes().make_signed(); }
670 U32x1 mask() const { M_insist(bool(mask_), "must call `setup()` before"); return *mask_; }
672 U32x1 capacity() const { return mask() + 1U; }
674 U32x1 size_in_bytes() const { return capacity() * uint32_t(sizeof(uint32_t)); }
675
676 public:
680 void setup() override;
684 void teardown() override;
685
688 void set_high_watermark(double percentage) override {
689 if (percentage < 1.0) {
690 std::cerr << "warning: using chained collisions the load factor must be in [1,∞), ignore invalid value "
691 << percentage << std::endl;
692 return;
693 }
694 high_watermark_percentage_ = percentage;
696 }
697 private:
700 M_insist(bool(high_watermark_absolute_), "must call `setup()` before");
701 auto high_watermark_absolute_new = high_watermark_percentage_ * capacity().make_signed().template to<double>();
702 auto high_watermark_absolute_floored = high_watermark_absolute_new.template to<int32_t>().make_unsigned();
703 Wasm_insist(high_watermark_absolute_floored.clone() >= 1U,
704 "at least one entry must be allowed to insert before growing the table");
705 *high_watermark_absolute_ = high_watermark_absolute_floored;
706 }
707
711 predication_dummy_.emplace(); // since globals cannot be constructed with runtime values
712 *predication_dummy_ = Module::Allocator().allocate(sizeof(uint32_t), sizeof(uint32_t));
713 *predication_dummy_->template to<uint32_t*>() = 0U; // set to nullptr
714 }
715
716 public:
717 void clear() override;
718
719 Ptr<void> compute_bucket(std::vector<SQL_t> key) const override;
720
721 entry_t emplace(std::vector<SQL_t> key) override;
722 std::pair<entry_t, Boolx1> try_emplace(std::vector<SQL_t> key) override;
723
724 std::pair<entry_t, Boolx1> find(std::vector<SQL_t> key, hint_t bucket_hint) override;
725
726 void for_each(callback_t Pipeline) const override;
727 void for_each_in_equal_range(std::vector<SQL_t> key, callback_t Pipeline, bool predicated,
728 hint_t bucket_hint) const override;
729
730 entry_t dummy_entry() override;
731
732 private:
734 Ptr<void> hash_to_bucket(std::vector<SQL_t> key) const;
735
740 entry_t emplace_without_rehashing(std::vector<SQL_t> key);
741
743 Boolx1 equal_key(Ptr<void> entry, std::vector<SQL_t> key) const;
744
746 void insert_key(Ptr<void> entry, std::vector<SQL_t> key);
747
754
758 void rehash();
759};
760
763
764
765/*----- open addressing hash tables ----------------------------------------------------------------------------------*/
766
768{
769 friend struct ProbingStrategy;
770
771 using ref_t = uint32_t;
772
775 {
776 protected:
778
779 public:
781
782 virtual ~ProbingStrategy() { }
783
785 virtual Ptr<void> skip_slots(Ptr<void> bucket, U32x1 skips) const = 0;
788 virtual Ptr<void> advance_to_next_slot(Ptr<void> slot, U32x1 current_step) const = 0;
789 };
790
791 protected:
792 std::unique_ptr<ProbingStrategy> probing_strategy_;
797
798 public:
800 OpenAddressingHashTableBase(const Schema &schema, std::vector<index_t> key_indices)
801 : HashTable(schema, std::move(key_indices))
802 { }
803
805 virtual Ptr<void> begin() const = 0;
807 virtual Ptr<void> end() const = 0;
810 virtual U32x1 mask() const = 0;
812 U32x1 capacity() const { return mask() + 1U; }
814 U32x1 size_in_bytes() const { return capacity() * entry_size_in_bytes_; }
817
819 template<typename T>
820 void set_probing_strategy() { probing_strategy_ = std::make_unique<T>(*this); }
821 protected:
824
826 Reference<ref_t> reference_count(Ptr<void> entry) const { return *(entry + refs_offset_in_bytes_).to<ref_t*>(); }
827
828 public:
831 void set_high_watermark(double percentage) override {
832 if (percentage < 0.5 or percentage >= 1.0) {
833 std::cerr << "warning: using open addressing the load factor must be in [0.5,1), ignore invalid value "
834 << percentage << std::endl;
835 return;
836 }
837 high_watermark_percentage_ = percentage;
839 }
840 protected:
842 virtual void update_high_watermark() { }
843
844 public:
845 void clear() override;
846
847 protected:
849 Ptr<void> hash_to_bucket(std::vector<SQL_t> key) const;
850};
851
852template<bool ValueInPlace>
854
855template<>
857{
858 friend struct OpenAddressingHashTable<false, true>;
859 friend struct OpenAddressingHashTable<true, true>;
860
861 std::vector<HashTable::offset_t> entry_offsets_in_bytes_;
863};
864
865template<>
867{
868 friend struct OpenAddressingHashTable<false, false>;
869 friend struct OpenAddressingHashTable<true, false>;
870
871 std::vector<HashTable::offset_t> key_offsets_in_bytes_;
872 std::vector<HashTable::offset_t> value_offsets_in_bytes_;
877 HashTable::offset_t values_null_bitmap_offset_in_bytes_;
878};
879
880template<bool IsGlobal>
882
883template<>
885
886template<>
888{
889 friend struct OpenAddressingHashTable<true, false>;
890 friend struct OpenAddressingHashTable<true, true>;
891
896};
897
898template<bool IsGlobal, bool ValueInPlace>
900{
901 private:
903 template<typename T>
904 using var_t = std::conditional_t<IsGlobal, Global<T>, Var<T>>;
905
907 std::optional<Var<Ptr<void>>> address_;
908 std::optional<Var<U32x1>> mask_;
909 std::optional<Var<U32x1>> num_entries_;
910 std::optional<Var<U32x1>> high_watermark_absolute_;
914 std::optional<FunctionProxy<void(void)>> rehash_;
915 std::vector<std::pair<Ptr<void>, U32x1>> dummy_allocations_;
916 std::optional<var_t<Ptr<void>>> predication_dummy_;
917
918 public:
922 OpenAddressingHashTable(const Schema &schema, std::vector<HashTable::index_t> key_indices,
923 uint32_t initial_capacity);
924
926
928
929 private:
930 Ptr<void> begin() const override { M_insist(bool(address_), "must call `setup()` before"); return *address_; }
931 Ptr<void> end() const override { return begin() + (capacity() * entry_size_in_bytes_).make_signed(); }
932 U32x1 mask() const override { M_insist(bool(mask_), "must call `setup()` before"); return *mask_; }
933
934 public:
938 void setup() override;
942 void teardown() override;
943
944 private:
945 void update_high_watermark() override {
946 M_insist(bool(high_watermark_absolute_), "must call `setup()` before");
947 auto _capacity = capacity().make_signed().template to<double>();
948 const Var<U32x1> high_watermark_absolute_new(
949 (high_watermark_percentage_ * _capacity).ceil().template to<int32_t>().make_unsigned()
950 );
952 Select(capacity() <= high_watermark_absolute_new, capacity() - 1U, high_watermark_absolute_new);
954 "at least one entry must be allowed to insert before growing the table");
955 Wasm_insist(*high_watermark_absolute_ < capacity(), "at least one entry must always be unoccupied for lookups");
956 }
957
961 predication_dummy_.emplace(); // since globals cannot be constructed with runtime values
964 reference_count(*predication_dummy_) = ref_t(0); // set unoccupied
965 }
966
967 public:
968 Ptr<void> compute_bucket(std::vector<SQL_t> key) const override;
969
970 entry_t emplace(std::vector<SQL_t> key) override;
971 std::pair<entry_t, Boolx1> try_emplace(std::vector<SQL_t> key) override;
972
973 std::pair<entry_t, Boolx1> find(std::vector<SQL_t> key, hint_t bucket_hint) override;
974
975 void for_each(callback_t Pipeline) const override;
976 void for_each_in_equal_range(std::vector<SQL_t> key, callback_t Pipeline, bool predicated,
977 hint_t bucket_hint) const override;
978
979 entry_t dummy_entry() override;
980
981 private:
986 Ptr<void> emplace_without_rehashing(std::vector<SQL_t> key);
987
989 Boolx1 equal_key(Ptr<void> slot, std::vector<SQL_t> key) const;
990
992 void insert_key(Ptr<void> slot, std::vector<SQL_t> key);
993
997 entry_t value_entry(Ptr<void> ptr) const;
1000 const_entry_t entry(Ptr<void> slot) const;
1001
1005 void rehash();
1006};
1007
1012
1013
1014/*----- probing strategies for open addressing hash tables -----------------------------------------------------------*/
1015
1018{
1020
1021 Ptr<void> skip_slots(Ptr<void> bucket, U32x1 skips) const override;
1022 Ptr<void> advance_to_next_slot(Ptr<void> slot, U32x1 current_step) const override;
1023};
1024
1028{
1030
1031 Ptr<void> skip_slots(Ptr<void> bucket, U32x1 skips) const override;
1032 Ptr<void> advance_to_next_slot(Ptr<void> slot, U32x1 current_step) const override;
1033};
1034
1035
1036/*======================================================================================================================
1037 * explicit instantiation declarations
1038 *====================================================================================================================*/
1039
1040extern template void quicksort<false>(GlobalBuffer&, const std::vector<SortingOperator::order_type>&);
1041extern template void quicksort<true>(GlobalBuffer&, const std::vector<SortingOperator::order_type>&);
1042extern template struct m::wasm::ChainedHashTable<false>;
1043extern template struct m::wasm::ChainedHashTable<true>;
1048
1049}
1050
1051}
#define ADD_TYPE(TYPE)
#define Wasm_insist(...)
Definition: WasmDSL.hpp:373
#define IF(COND)
Definition: WasmMacro.hpp:23
#define SQL_TYPES_SCALAR(X)
Definition: WasmUtil.hpp:302
Global< Ptr< void > > address_
global backup for address of hash table
Definition: WasmAlgo.hpp:618
Global< U32x1 > num_entries_
global backup for number of occupied entries of hash table
Definition: WasmAlgo.hpp:620
Global< U32x1 > mask_
global backup for mask of hash table
Definition: WasmAlgo.hpp:619
Global< U32x1 > high_watermark_absolute_
global backup for absolute high watermark of hash table
Definition: WasmAlgo.hpp:621
std::vector< HashTable::offset_t > value_offsets_in_bytes_
Definition: WasmAlgo.hpp:872
HashTable::offset_t keys_null_bitmap_offset_in_bytes_
only specified if at least one key entry is nullable
Definition: WasmAlgo.hpp:876
std::vector< HashTable::offset_t > key_offsets_in_bytes_
Definition: WasmAlgo.hpp:871
HashTable::offset_t ptr_offset_in_bytes_
pointer to out-of-place values
Definition: WasmAlgo.hpp:873
HashTable::offset_t null_bitmap_offset_in_bytes_
only specified if at least one entry is nullable
Definition: WasmAlgo.hpp:862
std::vector< HashTable::offset_t > entry_offsets_in_bytes_
Definition: WasmAlgo.hpp:861
Global< U32x1 > num_entries_
global backup for number of occupied entries of hash table
Definition: WasmAlgo.hpp:894
Global< U32x1 > high_watermark_absolute_
global backup for absolute high watermark of hash table
Definition: WasmAlgo.hpp:895
Global< Ptr< void > > address_
global backup for address of hash table
Definition: WasmAlgo.hpp:892
Global< U32x1 > mask_
global backup for mask of hash table
Definition: WasmAlgo.hpp:893
#define M_unreachable(MSG)
Definition: macro.hpp:146
#define M_insist(...)
Definition: macro.hpp:129
_I32x1 strncmp(NChar left, NChar right, U32x1 len, bool reverse=false)
Compares two strings left and right.
Definition: WasmUtil.cpp:3102
template void quicksort< true >(GlobalBuffer &, const std::vector< SortingOperator::order_type > &)
Ptr< Charx1 > strncpy(Ptr< Charx1 > dst, Ptr< Charx1 > src, U32x1 count)
Copies the contents of src to dst, but no more than count characters.
Definition: WasmUtil.cpp:3311
To ToL to()
Definition: WasmDSL.hpp:1985
U64x1 str_hash(NChar str)
Hashes the string str.
Definition: WasmAlgo.cpp:313
template void quicksort< false >(GlobalBuffer &, const std::vector< SortingOperator::order_type > &)
typename detail::var_helper< T >::type Var
Local variable.
Definition: WasmDSL.hpp:5779
auto make_unsigned()
Conversion of a PrimitiveExpr<T, L> to a PrimitiveExpr<std::make_unsigned_t<T>, L>.
Definition: WasmDSL.hpp:3658
auto make_signed()
Conversion of a PrimitiveExpr<T, L> to a PrimitiveExpr<std::make_signed_t<T>, L>.
Definition: WasmDSL.hpp:3650
U64x1 murmur3_bit_mix(U64x1 bits)
Mixes the bits of bits using the Murmur3 algorithm.
Definition: WasmAlgo.cpp:280
void quicksort(Buffer< IsGlobal > &buffer, const std::vector< SortingOperator::order_type > &order)
Sorts the buffer buffer using the quicksort algorithm and a branchless binary partition algorithm.
Definition: WasmAlgo.cpp:64
and
Constructs a new PrimitiveExpr from a constant value.
Definition: WasmDSL.hpp:1519
typename detail::global_helper< T >::type Global
Global variable.
Definition: WasmDSL.hpp:5789
Bool< L > value
Definition: WasmUtil.hpp:1317
Bool< L > is_null(SQL_t &variant)
Definition: WasmUtil.hpp:461
PrimitiveExpr< uint64_t, L > L L L L U
Definition: WasmDSL.hpp:2352
U64x1 fnv_1a(Ptr< U8x1 > bytes, U32x1 num_bytes)
Hashes num_bytes bytes of bytes using the FNV-1a algorithm.
Definition: WasmAlgo.cpp:297
std::pair<::wasm::Expression *, std::list< std::shared_ptr< Bit > > > move()
Moves the underlying Binaryen ::wasm::Expression and the referenced bits out of this.
Definition: WasmDSL.hpp:1567
U64x1 murmur3_64a_hash(std::vector< std::pair< const Type *, SQL_t > > values)
Hashes the elements of values where the first element is the type of the value to hash and the second...
Definition: WasmAlgo.cpp:338
‍mutable namespace
Definition: Backend.hpp:10
bool M_EXPORT contains(const H &haystack, const N &needle)
Checks whether haystack contains needle.
Definition: fn.hpp:383
T(x)
void M_EXPORT setbit(T *bytes, bool value, uint32_t n)
Definition: fn.hpp:442
STL namespace.
Implements push-based evaluation of a pipeline in the plan.
An Identifier is composed of a name and an optional prefix.
Definition: Schema.hpp:42
A Schema represents a sequence of identifiers, optionally with a prefix, and their associated types.
Definition: Schema.hpp:39
std::size_t num_entries() const
Returns the number of entries in this Schema.
Definition: Schema.hpp:124
Buffers tuples by materializing them into memory.
Definition: WasmUtil.hpp:1070
void rehash()
Performs rehashing, i.e.
Definition: WasmAlgo.cpp:1205
std::optional< FunctionProxy< void(void)> > rehash_
‍function to perform rehashing; only possible for global hash tables since variables have to be updat...
Definition: WasmAlgo.hpp:649
void update_high_watermark()
Updates internal high watermark variables according to the currently set high watermark percentage.
Definition: WasmAlgo.hpp:699
HashTable::offset_t null_bitmap_offset_in_bytes_
‍offset of NULL bitmap; only specified if at least one entry is nullable
Definition: WasmAlgo.hpp:636
std::optional< Var< U32x1 > > high_watermark_absolute_
‍maximum number of entries before growing the hash table is required
Definition: WasmAlgo.hpp:645
Ptr< void > begin() const
Returns the address of the first bucket, i.e.
Definition: WasmAlgo.hpp:665
std::vector< std::pair< Ptr< void >, U32x1 > > dummy_allocations_
address-size pairs of dummy entry allocations
Definition: WasmAlgo.hpp:650
Ptr< void > end() const
Returns the address of the past-the-end bucket.
Definition: WasmAlgo.hpp:667
void setup() override
Performs the setup of all local variables of the hash table (by reading them from the global backups ...
Definition: WasmAlgo.cpp:569
U32x1 capacity() const
Returns the capacity of the hash table.
Definition: WasmAlgo.hpp:672
void clear() override
Clears the hash table.
Definition: WasmAlgo.cpp:674
std::pair< entry_t, Boolx1 > find(std::vector< SQL_t > key, hint_t bucket_hint) override
Tries to find an entry with key key in the hash table.
Definition: WasmAlgo.cpp:873
void for_each_in_equal_range(std::vector< SQL_t > key, callback_t Pipeline, bool predicated, hint_t bucket_hint) const override
Calls Pipeline for each entry with key key in the hash table, where the key comparison is performed p...
Definition: WasmAlgo.cpp:909
void for_each(callback_t Pipeline) const override
Calls Pipeline for each entry contained in the hash table.
Definition: WasmAlgo.cpp:893
U32x1 size_in_bytes() const
Returns the overall size in bytes of the actual hash table, i.e.
Definition: WasmAlgo.hpp:674
entry_t value_entry(Ptr< void > entry) const
Returns a handle for the entry at address entry which may be used to write the values of the correspo...
Definition: WasmAlgo.cpp:1075
HashTable::offset_t ptr_offset_in_bytes_
offset of pointer to next entry in linked collision list
Definition: WasmAlgo.hpp:637
HashTable::size_t entry_size_in_bytes_
entry size in bytes
Definition: WasmAlgo.hpp:632
Boolx1 equal_key(Ptr< void > entry, std::vector< SQL_t > key) const
Compares the key of the entry at address entry with key and returns true iff they are equal.
Definition: WasmAlgo.cpp:945
std::pair< entry_t, Boolx1 > try_emplace(std::vector< SQL_t > key) override
If no entry with key key already exists, inserts one into the hash table, i.e.
Definition: WasmAlgo.cpp:796
std::optional< var_t< Ptr< void > > > predication_dummy_
dummy bucket used for predication
Definition: WasmAlgo.hpp:651
entry_t emplace_without_rehashing(std::vector< SQL_t > key)
Inserts an entry into the hash table with key key regardless whether it already exists,...
Definition: WasmAlgo.cpp:754
void teardown() override
Performs the teardown of all local variables of the hash table (by storing them into the global backu...
Definition: WasmAlgo.cpp:615
std::optional< Var< U32x1 > > num_entries_
number of occupied entries of hash table
Definition: WasmAlgo.hpp:642
void set_high_watermark(double percentage) override
Sets the high watermark, i.e.
Definition: WasmAlgo.hpp:688
HashTable::size_t entry_max_alignment_in_bytes_
alignment requirement in bytes of a single entry
Definition: WasmAlgo.hpp:633
std::vector< HashTable::offset_t > entry_offsets_in_bytes_
entry offsets, i.e.
Definition: WasmAlgo.hpp:634
void insert_key(Ptr< void > entry, std::vector< SQL_t > key)
Inserts the key key into the entry at address entry.
Definition: WasmAlgo.cpp:1010
std::optional< Var< Ptr< void > > > address_
base address of hash table
Definition: WasmAlgo.hpp:639
chained_hash_table_storage< IsGlobal > storage_
‍if IsGlobal, contains backups for address, capacity, number of entries, and absolute high watermark
Definition: WasmAlgo.hpp:647
U32x1 mask() const
Returns the mask of the hash table, i.e.
Definition: WasmAlgo.hpp:670
Ptr< void > compute_bucket(std::vector< SQL_t > key) const override
Computes the bucket for key key.
Definition: WasmAlgo.cpp:717
entry_t dummy_entry() override
Returns a handle to a newly created dummy entry which may be used to write the values for this entry.
Definition: WasmAlgo.cpp:931
const_entry_t entry(Ptr< void > entry) const
Returns a handle for the entry at address entry which may be used to read both the keys and the value...
Definition: WasmAlgo.cpp:1138
std::optional< Var< U32x1 > > mask_
‍mask of hash table, i.e. number of buckets / collision lists minus 1; always a power of 2 minus 1
Definition: WasmAlgo.hpp:641
void create_predication_dummy()
Creates dummy entry for predication.
Definition: WasmAlgo.hpp:709
ChainedHashTable(ChainedHashTable &&)=default
Ptr< void > hash_to_bucket(std::vector< SQL_t > key) const
Returns the bucket address for the key key by hashing it.
Definition: WasmAlgo.cpp:693
std::conditional_t< IsGlobal, Global< T >, Var< T > > var_t
‍variable type dependent on whether the hash table should be globally usable
Definition: WasmAlgo.hpp:630
entry_t emplace(std::vector< SQL_t > key) override
Inserts an entry into the hash table with key key regardless whether it already exists,...
Definition: WasmAlgo.cpp:739
double high_watermark_percentage_
fraction of occupied entries before growing the hash table is required
Definition: WasmAlgo.hpp:643
A handle to create a Function and to create invocations of that function.
Definition: WasmDSL.hpp:1367
Helper struct as proxy to access a hash table entry.
Definition: WasmAlgo.hpp:369
bool has(const Schema::Identifier &id) const
‍Returns true iff this contains identifier id.
Definition: WasmAlgo.hpp:434
the_reference< T, IsConst > extract(const Schema::Identifier &id)
‍Returns the moved entry for identifier id.
Definition: WasmAlgo.hpp:451
value_t get(const Schema::Identifier &id) const
‍Returns the copied entry for identifier id.
Definition: WasmAlgo.hpp:462
static void discard(value_t &ref)
‍Discards the held reference of ref.
Definition: WasmAlgo.hpp:381
the_entry(const the_entry &)=delete
std::variant< std::monostate #define ADD_TYPE(TYPE) SQL_TYPES_SCALAR(ADD_TYPE) > value_t
Definition: WasmAlgo.hpp:377
bool empty() const
‍Returns true iff this does not contain any references.
Definition: WasmAlgo.hpp:431
the_entry(std::unordered_multimap< Schema::Identifier, typename the_entry< not IsConst >::value_t > refs)
‍constructs an entry from references of the opposite const-ness
Definition: WasmAlgo.hpp:400
std::unordered_multimap< Schema::Identifier, value_t > refs_
‍maps Schema::Identifiers to the_reference<T, IsConst>s that reference the stored expression,...
Definition: WasmAlgo.hpp:391
the_entry(the_entry &&)=default
~the_entry()
Definition: WasmAlgo.hpp:422
the_entry()=default
value_t extract(const Schema::Identifier &id)
‍Returns the moved entry for identifier id.
Definition: WasmAlgo.hpp:443
void add(Schema::Identifier id, the_reference< T, IsConst > &&ref)
‍Adds a mapping from identifier id to reference ref.
Definition: WasmAlgo.hpp:438
Boolx1 operator==(NChar _addr)
‍Compares this with the string stored at _addr.
Definition: WasmAlgo.hpp:307
friend the_reference Select(Boolx1 cond, the_reference tru, the_reference fals)
‍Selects either the reference tru or fals depending on the value of cond.
Definition: WasmAlgo.hpp:338
the_reference(NChar addr, Ptr< U8x1 > is_null_byte, U8x1 is_null_mask)
Definition: WasmAlgo.hpp:220
void operator=(NChar addr)
‍Assigns this to the string stored at addr.
Definition: WasmAlgo.hpp:259
the_reference clone() const
‍Returns a deep copy of this.
Definition: WasmAlgo.hpp:251
void set_null_bit(Boolx1 is_null)
‍Assigns the NULL bit of this to is_null. Does not update/modify the value of this.
Definition: WasmAlgo.hpp:285
void set_not_null()
‍Sets this to NOT NULL. Does not modify the value of this.
Definition: WasmAlgo.hpp:299
the_reference(NChar addr, Ptr< void > null_bitmap, uint8_t null_bit_offset)
Definition: WasmAlgo.hpp:234
void set_null()
‍Sets this to NULL. Does not modify the value of this.
Definition: WasmAlgo.hpp:292
the_reference(NChar addr, std::optional< Ptr< U8x1 > > is_null_byte, std::optional< U8x1 > is_null_mask)
Definition: WasmAlgo.hpp:211
void set_value(NChar addr)
‍Assigns the value of this to the string stored at addr w/o updating the NULL bit.
Definition: WasmAlgo.hpp:274
Helper struct as proxy to access a single value (inclusive NULL bit) of a hash table entry.
Definition: WasmAlgo.hpp:66
Hash table to hash key-value pairs in memory.
Definition: WasmAlgo.hpp:56
the_reference(Ptr< value_t > value, Ptr< void > null_bitmap, uint8_t null_bit_offset)
Definition: WasmAlgo.hpp:98
static std::vector< SQL_t > clone(const std::vector< SQL_t > &values)
‍Copies the vector of SQL_ts values.
Definition: WasmAlgo.hpp:491
virtual void teardown()=0
Performs the teardown of the hash table.
std::size_t index_t
Definition: WasmAlgo.hpp:57
void discard()
‍Discards this.
Definition: WasmAlgo.hpp:105
friend the_reference Select(Boolx1 cond, the_reference tru, the_reference fals)
‍Selects either the reference tru or fals depending on the value of cond.
Definition: WasmAlgo.hpp:183
std::optional< U8x1 > is_null_mask_
Definition: WasmAlgo.hpp:80
void set_null()
‍Sets this to NULL. Does not modify the value of this.
Definition: WasmAlgo.hpp:148
the_reference(Ptr< value_t > value)
Definition: WasmAlgo.hpp:97
virtual std::pair< entry_t, Boolx1 > try_emplace(std::vector< SQL_t > key)=0
If no entry with key key already exists, inserts one into the hash table, i.e.
virtual entry_t dummy_entry()=0
Returns a handle to a newly created dummy entry which may be used to write the values for this entry.
virtual void setup()=0
Performs the setup of the hash table.
virtual ~HashTable()
Definition: WasmAlgo.hpp:529
void set_value(value_t value)
‍Assigns the value of this to value w/o updating the NULL bit.
Definition: WasmAlgo.hpp:132
the_reference(Ptr< value_t > value, Ptr< U8x1 > is_null_byte, U8x1 is_null_mask)
Definition: WasmAlgo.hpp:90
virtual entry_t emplace(std::vector< SQL_t > key)=0
Inserts an entry into the hash table with key key regardless whether it already exists,...
virtual void set_high_watermark(double percentage)=0
Sets the high watermark, i.e.
std::vector< index_t > key_indices_
keys of hash table
Definition: WasmAlgo.hpp:505
HashTable(const HashTable &)=delete
std::pair< const_entry_t, Boolx1 > find(std::vector< SQL_t > key, hint_t bucket_hint=hint_t()) const
Tries to find an entry with key key in the hash table.
Definition: WasmAlgo.hpp:573
void set_not_null()
‍Sets this to NOT NULL. Does not modify the value of this.
Definition: WasmAlgo.hpp:155
void operator=(T _value)
‍Assigns this to _value.
Definition: WasmAlgo.hpp:121
std::vector< index_t > value_indices_
values of hash table
Definition: WasmAlgo.hpp:506
std::function< void(const_entry_t)> callback_t
Definition: WasmAlgo.hpp:486
virtual Ptr< void > compute_bucket(std::vector< SQL_t > key) const =0
Computes the bucket for key key.
const Schema & schema() const
Definition: WasmAlgo.hpp:531
Ptr< value_t > value_
Definition: WasmAlgo.hpp:78
the_entry< false > entry_t
Definition: WasmAlgo.hpp:483
virtual std::pair< entry_t, Boolx1 > find(std::vector< SQL_t > key, hint_t bucket_hint=hint_t())=0
Tries to find an entry with key key in the hash table.
std::optional< Ptr< U8x1 > > is_null_byte_
Definition: WasmAlgo.hpp:79
std::optional< Ptr< void > > hint_t
Definition: WasmAlgo.hpp:487
virtual void for_each(callback_t Pipeline) const =0
Calls Pipeline for each entry contained in the hash table.
the_entry< true > const_entry_t
Definition: WasmAlgo.hpp:484
std::reference_wrapper< const Schema > schema_
schema of hash table
Definition: WasmAlgo.hpp:504
std::pair< size_t, size_t > set_byte_offsets(std::vector< offset_t > &offsets_in_bytes, const std::vector< const Type * > &types, offset_t initial_offset_in_bytes=0, offset_t initial_max_alignment_in_bytes=1)
Sets the byte offsets of an entry containing values of types types in offsets_in_bytes with the start...
Definition: WasmAlgo.cpp:438
Boolx1 operator==(T _value)
‍Compares this with _value.
Definition: WasmAlgo.hpp:163
HashTable(const Schema &schema, std::vector< index_t > key_indices)
Creates a hash table with schema schema and keys at key_indices.
Definition: WasmAlgo.hpp:512
the_reference(Ptr< value_t > value, std::optional< Ptr< U8x1 > > is_null_byte, std::optional< U8x1 > is_null_mask)
Definition: WasmAlgo.hpp:82
friend struct the_entry< true >
Definition: WasmAlgo.hpp:73
the_reference clone() const
‍Returns a deep copy of this.
Definition: WasmAlgo.hpp:113
virtual void for_each_in_equal_range(std::vector< SQL_t > key, callback_t Pipeline, bool predicated=false, hint_t bucket_hint=hint_t()) const =0
Calls Pipeline for each entry with key key in the hash table, where the key comparison is performed p...
virtual void clear()=0
Clears the hash table.
void set_null_bit(Boolx1 is_null)
‍Assigns the NULL bit of this to is_null. Does not update/modify the value of this.
Definition: WasmAlgo.hpp:141
HashTable(HashTable &&)=default
Linear probing strategy, i.e.
Definition: WasmAlgo.hpp:1018
Ptr< void > skip_slots(Ptr< void > bucket, U32x1 skips) const override
Returns the address of the skips -th (starting with index 0) slot in the bucket starting at bucket.
Definition: WasmAlgo.cpp:2384
Ptr< void > advance_to_next_slot(Ptr< void > slot, U32x1 current_step) const override
Returns the address of the current_step -th slot (starting with index 0) of a bucket which follows th...
Definition: WasmAlgo.cpp:2392
LinearProbing(const OpenAddressingHashTableBase &ht)
Definition: WasmAlgo.hpp:1019
friend struct Allocator
Definition: WasmDSL.hpp:652
std::size_t length() const
Definition: WasmUtil.hpp:81
bool guarantees_terminating_nul() const
Definition: WasmUtil.hpp:83
NChar clone() const
Definition: WasmUtil.hpp:53
bool can_be_null() const
Definition: WasmUtil.hpp:80
Ptr< Charx1 > val()
Definition: WasmUtil.hpp:55
Probing strategy to handle collisions in an open addressing hash table.
Definition: WasmAlgo.hpp:775
ProbingStrategy(const OpenAddressingHashTableBase &ht)
Definition: WasmAlgo.hpp:780
virtual Ptr< void > skip_slots(Ptr< void > bucket, U32x1 skips) const =0
Returns the address of the skips -th (starting with index 0) slot in the bucket starting at bucket.
virtual Ptr< void > advance_to_next_slot(Ptr< void > slot, U32x1 current_step) const =0
Returns the address of the current_step -th slot (starting with index 0) of a bucket which follows th...
const OpenAddressingHashTableBase & ht_
open addressing hash table which uses this probing strategy
Definition: WasmAlgo.hpp:777
HashTable::offset_t refs_offset_in_bytes_
offset in bytes for reference counter
Definition: WasmAlgo.hpp:793
HashTable::size_t entry_size_in_bytes() const
Returns the size in bytes of a single entry in the hash table.
Definition: WasmAlgo.hpp:816
double high_watermark_percentage_
fraction of occupied entries before growing the hash table is required
Definition: WasmAlgo.hpp:796
virtual Ptr< void > begin() const =0
Returns the address of the first entry.
void set_high_watermark(double percentage) override
Sets the high watermark, i.e.
Definition: WasmAlgo.hpp:831
HashTable::size_t entry_size_in_bytes_
entry size in bytes
Definition: WasmAlgo.hpp:794
Reference< ref_t > reference_count(Ptr< void > entry) const
Returns a Reference to the reference counter for the entry at address entry.
Definition: WasmAlgo.hpp:826
U32x1 size_in_bytes() const
Returns the overall size in bytes of the hash table.
Definition: WasmAlgo.hpp:814
std::unique_ptr< ProbingStrategy > probing_strategy_
probing strategy to handle collisions
Definition: WasmAlgo.hpp:792
virtual U32x1 mask() const =0
Returns the mask of the hash table, i.e.
const ProbingStrategy & probing_strategy() const
Returns the currently used probing strategy of the hash table.
Definition: WasmAlgo.hpp:823
void clear() override
Clears the hash table.
Definition: WasmAlgo.cpp:1322
void set_probing_strategy()
Sets the hash table's probing strategy to.
Definition: WasmAlgo.hpp:820
virtual Ptr< void > end() const =0
Returns the address of the past-the-end entry.
Ptr< void > hash_to_bucket(std::vector< SQL_t > key) const
Returns the bucket address for the key key by hashing it.
Definition: WasmAlgo.cpp:1332
uint32_t ref_t
4 bytes for reference counting
Definition: WasmAlgo.hpp:771
OpenAddressingHashTableBase(const Schema &schema, std::vector< index_t > key_indices)
Creates an open addressing hash table with schema schema and keys at key_indices.
Definition: WasmAlgo.hpp:800
HashTable::size_t entry_max_alignment_in_bytes_
alignment requirement in bytes of a single entry
Definition: WasmAlgo.hpp:795
virtual void update_high_watermark()
Updates internal high watermark variables according to the currently set high watermark percentage.
Definition: WasmAlgo.hpp:842
U32x1 capacity() const
Returns the capacity of the hash table.
Definition: WasmAlgo.hpp:812
Boolx1 equal_key(Ptr< void > slot, std::vector< SQL_t > key) const
Compares the key of the slot at address slot with key and returns true iff they are equal.
Definition: WasmAlgo.cpp:1904
std::optional< Var< U32x1 > > high_watermark_absolute_
maximum number of entries before growing the hash table is required
Definition: WasmAlgo.hpp:910
const_entry_t entry(Ptr< void > slot) const
Returns a handle for the slot at address slot which may be used to read both the keys and the values ...
Definition: WasmAlgo.cpp:2133
open_addressing_hash_table_storage< IsGlobal > storage_
‍if IsGlobal, contains backups for address, capacity, number of entries, and absolute high watermark
Definition: WasmAlgo.hpp:912
std::optional< var_t< Ptr< void > > > predication_dummy_
dummy entry used for predication
Definition: WasmAlgo.hpp:916
void for_each(callback_t Pipeline) const override
Calls Pipeline for each entry contained in the hash table.
Definition: WasmAlgo.cpp:1830
void teardown() override
Performs the teardown of all local variables of the hash table (by storing them into the global backu...
Definition: WasmAlgo.cpp:1550
std::optional< FunctionProxy< void(void)> > rehash_
‍function to perform rehashing; only possible for global hash tables since variables have to be updat...
Definition: WasmAlgo.hpp:914
std::optional< Var< U32x1 > > num_entries_
number of occupied entries of hash table
Definition: WasmAlgo.hpp:909
void rehash()
Performs rehashing, i.e.
Definition: WasmAlgo.cpp:2231
std::optional< Var< U32x1 > > mask_
mask of hash table; always a power of 2 minus 1, i.e. 0b0..01..1
Definition: WasmAlgo.hpp:908
void update_high_watermark() override
Updates internal high watermark variables according to the currently set high watermark percentage.
Definition: WasmAlgo.hpp:945
std::pair< entry_t, Boolx1 > try_emplace(std::vector< SQL_t > key) override
If no entry with key key already exists, inserts one into the hash table, i.e.
Definition: WasmAlgo.cpp:1702
entry_t value_entry(Ptr< void > ptr) const
Returns a handle which may be used to write the values of the corresponding entry.
Definition: WasmAlgo.cpp:2058
void setup() override
Performs the setup of all local variables of the hash table (by reading them from the global backups ...
Definition: WasmAlgo.cpp:1504
std::optional< Var< Ptr< void > > > address_
base address of hash table
Definition: WasmAlgo.hpp:907
std::pair< entry_t, Boolx1 > find(std::vector< SQL_t > key, hint_t bucket_hint) override
Tries to find an entry with key key in the hash table.
Definition: WasmAlgo.cpp:1794
Ptr< void > emplace_without_rehashing(std::vector< SQL_t > key)
Inserts an entry into the hash table with key key regardless whether it already exists,...
Definition: WasmAlgo.cpp:1645
U32x1 mask() const override
Returns the mask of the hash table, i.e.
Definition: WasmAlgo.hpp:932
void create_predication_dummy()
Creates dummy entry for predication.
Definition: WasmAlgo.hpp:959
std::vector< std::pair< Ptr< void >, U32x1 > > dummy_allocations_
address-size pairs of dummy entry allocations
Definition: WasmAlgo.hpp:915
Ptr< void > begin() const override
Returns the address of the first entry.
Definition: WasmAlgo.hpp:930
Ptr< void > end() const override
Returns the address of the past-the-end entry.
Definition: WasmAlgo.hpp:931
Ptr< void > compute_bucket(std::vector< SQL_t > key) const override
Computes the bucket for key key.
Definition: WasmAlgo.cpp:1595
entry_t emplace(std::vector< SQL_t > key) override
Inserts an entry into the hash table with key key regardless whether it already exists,...
Definition: WasmAlgo.cpp:1617
OpenAddressingHashTable(OpenAddressingHashTable &&)=default
void insert_key(Ptr< void > slot, std::vector< SQL_t > key)
Inserts the key key into the slot at address slot.
Definition: WasmAlgo.cpp:1981
std::conditional_t< IsGlobal, Global< T >, Var< T > > var_t
‍variable type dependent on whether the hash table should be globally usable
Definition: WasmAlgo.hpp:904
entry_t dummy_entry() override
Returns a handle to a newly created dummy entry which may be used to write the values for this entry.
Definition: WasmAlgo.cpp:1878
void for_each_in_equal_range(std::vector< SQL_t > key, callback_t Pipeline, bool predicated, hint_t bucket_hint) const override
Calls Pipeline for each entry with key key in the hash table, where the key comparison is performed p...
Definition: WasmAlgo.cpp:1844
open_addressing_hash_table_layout< ValueInPlace > layout_
layout of hash table
Definition: WasmAlgo.hpp:906
Quadratic probing strategy, i.e.
Definition: WasmAlgo.hpp:1028
Ptr< void > skip_slots(Ptr< void > bucket, U32x1 skips) const override
Returns the address of the skips -th (starting with index 0) slot in the bucket starting at bucket.
Definition: WasmAlgo.cpp:2401
QuadraticProbing(const OpenAddressingHashTableBase &ht)
Definition: WasmAlgo.hpp:1029
Ptr< void > advance_to_next_slot(Ptr< void > slot, U32x1 current_step) const override
Returns the address of the current_step -th slot (starting with index 0) of a bucket which follows th...
Definition: WasmAlgo.cpp:2411