xo-arena: DArenaHashMap: find() + utest
This commit is contained in:
parent
b5c4ea47f8
commit
4b73706625
3 changed files with 75 additions and 18 deletions
|
|
@ -457,6 +457,11 @@ namespace xo {
|
|||
/** reset to empty state **/
|
||||
void clear();
|
||||
|
||||
/** find element with key @p key.
|
||||
* @return iterator to element if found, end() otherwise
|
||||
**/
|
||||
iterator find(const key_type & key);
|
||||
|
||||
private:
|
||||
/** insert @p kv_pair,
|
||||
* where key hashes to @p hash_value, into @p *store
|
||||
|
|
@ -745,6 +750,59 @@ namespace xo {
|
|||
this->store_.clear();
|
||||
}
|
||||
|
||||
template <typename Key,
|
||||
typename Value,
|
||||
typename Hash,
|
||||
typename Equal>
|
||||
auto
|
||||
DArenaHashMap<Key, Value, Hash, Equal>::find(const key_type & key) -> iterator
|
||||
{
|
||||
size_type N = store_.capacity();
|
||||
|
||||
if (N == 0) [[unlikely]] {
|
||||
return this->end();
|
||||
}
|
||||
|
||||
size_type h = hash_(key);
|
||||
size_type h1 = h >> 7;
|
||||
uint8_t h2 = h & 0x7f;
|
||||
|
||||
size_type ix = h1 & (N - 1);
|
||||
|
||||
for (;;) {
|
||||
auto grp = store_._load_group(ix);
|
||||
|
||||
{
|
||||
uint16_t m = grp.all_matches(h2);
|
||||
|
||||
while (m) {
|
||||
int skip = __builtin_ctz(m);
|
||||
size_type slot_ix = (ix + skip) & (N - 1);
|
||||
|
||||
auto & slot = store_.slots_[slot_ix];
|
||||
|
||||
if (equal_(slot.first, key)) {
|
||||
return iterator(&(store_.control_[c_control_stub + slot_ix]),
|
||||
&(store_.control_[c_control_stub + N]),
|
||||
&slot);
|
||||
}
|
||||
|
||||
m &= (m - 1);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
uint16_t e = grp.empty_matches();
|
||||
|
||||
if (e) {
|
||||
return this->end();
|
||||
}
|
||||
}
|
||||
|
||||
ix = (ix + c_group_size) & (N - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify DArenaHashMap class invariants.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -208,6 +208,9 @@ namespace xo {
|
|||
ok_flag &= HashMapUtil<HashMap>::check_forward_iterator(0.0 /*dvalue*/,
|
||||
dbg_flag, hash_map);
|
||||
|
||||
ok_flag &= HashMapUtil<HashMap>::random_lookups(0.0 /*dvalue*/,
|
||||
dbg_flag, &rgen, hash_map);
|
||||
|
||||
return ok_flag;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -329,15 +329,15 @@ namespace utest {
|
|||
} /*random_removes*/
|
||||
#endif
|
||||
|
||||
#ifdef NOT_YET
|
||||
/* Require:
|
||||
* - tree has keys [0..n-1], where n=treẹsize()
|
||||
* - for each key k, associated value is 10*k
|
||||
* - map has keys [0..n-1], where n=map.size()
|
||||
* - for each key k, associated value is dvalue+10*k
|
||||
*/
|
||||
static bool
|
||||
random_lookups(bool catch_flag,
|
||||
Tree const & tree,
|
||||
xo::rng::xoshiro256ss * p_rgen)
|
||||
random_lookups(uint32_t dvalue,
|
||||
bool catch_flag,
|
||||
xo::rng::xoshiro256ss * p_rgen,
|
||||
HashMap & map)
|
||||
{
|
||||
using xo::scope;
|
||||
using xo::xtag;
|
||||
|
|
@ -347,9 +347,9 @@ namespace utest {
|
|||
/* -> false if/when verification fails */
|
||||
bool ok_flag = true;
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, tree.verify_ok(catch_flag));
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, map.verify_ok());
|
||||
|
||||
size_t n = tree.size();
|
||||
size_t n = map.size();
|
||||
std::vector<std::uint32_t> u
|
||||
= random_permutation(n, p_rgen);
|
||||
|
||||
|
|
@ -358,27 +358,23 @@ namespace utest {
|
|||
for (std::uint32_t x : u) {
|
||||
INFO(tostr(xtag("i", i), xtag("n", n), xtag("x", x)));
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, tree[x] == x*10);
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, tree.verify_ok(catch_flag));
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, tree.size() == n);
|
||||
auto find_ix = map.find(x);
|
||||
|
||||
/* also test treẹfind() */
|
||||
auto find_ix = tree.find(x);
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, find_ix != tree.end());
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, find_ix != map.end());
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, find_ix->first == x);
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, find_ix->second == x*10);
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, find_ix->second == dvalue + x*10);
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, map.verify_ok());
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, map.size() == n);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, tree.size() == n);
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, map.size() == n);
|
||||
|
||||
log.end_scope();
|
||||
|
||||
return ok_flag;
|
||||
} /*random_lookups*/
|
||||
#endif
|
||||
|
||||
/* Require:
|
||||
* - hash has keys [0..n-1] where n=map size
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue