forked from OctaForge/libostd
better multihash insertion strategy (make sure elements with equal keys always form a sequence in a bucket)
parent
8e40fca1ce
commit
71f5df79ce
|
@ -258,7 +258,7 @@ private:
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
Chain *insert(Size h) {
|
Chain *request_node() {
|
||||||
if (!p_unused) {
|
if (!p_unused) {
|
||||||
Chunk *chunk = allocator_allocate(get_challoc(), 1);
|
Chunk *chunk = allocator_allocate(get_challoc(), 1);
|
||||||
allocator_construct(get_challoc(), chunk);
|
allocator_construct(get_challoc(), chunk);
|
||||||
|
@ -272,7 +272,11 @@ private:
|
||||||
++p_len;
|
++p_len;
|
||||||
Chain *c = p_unused;
|
Chain *c = p_unused;
|
||||||
p_unused = p_unused->next;
|
p_unused = p_unused->next;
|
||||||
return insert_node(h, c);
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Chain *insert(Size h) {
|
||||||
|
return insert_node(h, request_node());
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_chunks(Chunk *chunks) {
|
void delete_chunks(Chunk *chunks) {
|
||||||
|
@ -511,13 +515,27 @@ public:
|
||||||
Pair<Range, bool> emplace(Args &&...args) {
|
Pair<Range, bool> emplace(Args &&...args) {
|
||||||
rehash_ahead(1);
|
rehash_ahead(1);
|
||||||
E elem(forward<Args>(args)...);
|
E elem(forward<Args>(args)...);
|
||||||
Size h = bucket(B::get_key(elem));
|
|
||||||
if (Multihash) {
|
if (Multihash) {
|
||||||
/* multihash: always insert */
|
/* multihash: always insert
|
||||||
Chain *ch = insert(h);
|
* gotta make sure that equal keys always come after
|
||||||
|
* each other (this is then used by other APIs)
|
||||||
|
*/
|
||||||
|
Size h = 0;
|
||||||
|
Chain *found = find(B::get_key(elem), h);
|
||||||
|
if (!found) {
|
||||||
|
Chain *ch = insert(h);
|
||||||
|
B::swap_elem(ch->value, elem);
|
||||||
|
return make_pair(Range(ch), true);
|
||||||
|
}
|
||||||
|
Chain *ch = request_node();
|
||||||
B::swap_elem(ch->value, elem);
|
B::swap_elem(ch->value, elem);
|
||||||
return make_pair(Range(ch), true);
|
Chain *next = found->next;
|
||||||
|
found->next = ch;
|
||||||
|
ch->prev = found;
|
||||||
|
ch->next = next;
|
||||||
|
if (next) next->prev = ch;
|
||||||
}
|
}
|
||||||
|
Size h = bucket(B::get_key(elem));
|
||||||
Chain *found = nullptr;
|
Chain *found = nullptr;
|
||||||
bool ins = true;
|
bool ins = true;
|
||||||
Chain **cp = p_data.first();
|
Chain **cp = p_data.first();
|
||||||
|
|
Loading…
Reference in New Issue