diff --git a/xo-arena/include/xo/arena/DArenaHashMap.hpp b/xo-arena/include/xo/arena/DArenaHashMap.hpp index ceb9961d..df6e15f8 100644 --- a/xo-arena/include/xo/arena/DArenaHashMap.hpp +++ b/xo-arena/include/xo/arena/DArenaHashMap.hpp @@ -60,6 +60,41 @@ namespace xo { }; #endif + /** @class DArenaHashMapUtil + * + * @pre + * + * control + * + * <----------------- control_size(n_slot) ----------------> + * <-stub-> <----------- n_slot ----------> <-stub-> + * +--------+-------------------------------+-------+--------+ + * | 0xF0 | empty / data / tombstone | wrap | 0xF0 | + * +--------+-------------------------------+-------+--------+ + * ^ ^ + * | ... | control_[stub+i] <--> slots_[i] + * slots v v + * +-------------------------------+ + * | {k,v} pairs | + * +-------------------------------+ + * <--- n_slot key-value pairs --> + * + * sizes: + * - stub before+after bookends. c_control_stub bytes (16) + * - group c_group_size. power of 2 (16 bytes) + * - n_slot hash table slots. power of 2 multiple of c_group_size. + * + * control bytes: + * - 0b1xxxxxxx sentinel bitmask + * - 0xf0 sentinel for before/after stubs (iterator bookends) + * - 0xff sentinel for empty slot. + * - 0xfe sentinel for tombstone + * - 0b0xxxxxxx high bit clear; remainder hold low 7 bits of hash + * - wrap duplicate first c_group_size bytes (after front stub) + * for SIMD convenience + * + * @endpre + **/ struct DArenaHashMapUtil { using size_type = std::size_t; using control_type = std::uint8_t; @@ -88,7 +123,7 @@ namespace xo { /** control: true for sentinel values **/ static constexpr bool is_sentinel(control_type ctrl) { - return ctrl & c_sentinel_mask; + return c_sentinel_mask == (ctrl & c_sentinel_mask); } /** control; true for non-sentinel values **/ @@ -254,7 +289,7 @@ namespace xo { /* end stub: iterator bookend */ std::fill(this->control_.end() - c_control_stub, this->control_.end(), - c_empty_slot); + c_iterator_bookend); this->slots_.resize(n_slot_); }