15 typedef typename TItem::Key Key;
17 TItem *first_item =
nullptr;
22 this->first_item =
nullptr;
30 inline const TItem *
Find(
const Key &key)
const
32 for (
const TItem *item = this->first_item; item !=
nullptr; item = item->GetHashNext()) {
33 if (item->GetKey() == key) {
46 inline TItem *
Find(
const Key &key)
48 for (TItem *item = this->first_item; item !=
nullptr; item = item->GetHashNext()) {
49 if (item->GetKey() == key) {
63 assert(new_item.GetHashNext() ==
nullptr);
64 new_item.SetHashNext(this->first_item);
65 this->first_item = &new_item;
73 inline bool Detach(TItem &item_to_remove)
75 if (this->first_item == &item_to_remove) {
76 this->first_item = item_to_remove.GetHashNext();
77 item_to_remove.SetHashNext(
nullptr);
80 TItem *item = this->first_item;
82 if (item ==
nullptr) {
85 TItem *next_item = item->GetHashNext();
86 if (next_item == &item_to_remove)
break;
89 item->SetHashNext(item_to_remove.GetHashNext());
90 item_to_remove.SetHashNext(
nullptr);
102 if (this->first_item ==
nullptr) {
106 if (this->first_item->GetKey() == key) {
107 TItem &ret_item = *this->first_item;
108 this->first_item = this->first_item->GetHashNext();
109 ret_item.SetHashNext(
nullptr);
113 TItem *previous_item = this->first_item;
114 for (TItem *item = this->first_item->GetHashNext(); item !=
nullptr; previous_item = item, item = item->GetHashNext()) {
115 if (item->GetKey() == key) {
117 previous_item->SetHashNext(item->GetHashNext());
118 item->SetHashNext(
nullptr);
148template <
class Titem,
int Thash_bits_>
151 typedef typename Titem::Key Tkey;
152 static constexpr int HASH_BITS = Thash_bits_;
153 static constexpr int CAPACITY = 1 << HASH_BITS;
172 uint32_t hash = key.CalcHash();
173 hash -= (hash >> 17);
175 hash &= (1 << HASH_BITS) - 1;
196 return this->number_of_items;
202 for (
int i = 0; i < CAPACITY; i++) this->slots[i].
Clear();
203 this->number_of_items = 0;
211 const Titem *
Find(
const Tkey &key)
const
214 const Slot &slot = this->slots[hash];
215 const Titem *item = slot.
Find(key);
227 Slot &slot = this->slots[hash];
228 Titem *item = slot.
Find(key);
240 Slot &slot = this->slots[hash];
241 Titem *item = slot.
Detach(key);
242 if (item !=
nullptr) {
243 this->number_of_items--;
253 Titem &
Pop(
const Tkey &key)
255 Titem *item =
TryPop(key);
256 assert(item !=
nullptr);
267 const Tkey &key = item.GetKey();
269 Slot &slot = this->slots[hash];
270 bool ret = slot.
Detach(item);
272 this->number_of_items--;
283 [[maybe_unused]]
bool ret =
TryPop(item);
294 Slot &slot = this->slots[hash];
295 assert(slot.
Find(new_item.GetKey()) ==
nullptr);
297 this->number_of_items++;
class HashTable<Titem, HASH_BITS> - simple hash table of pointers allocated elsewhere.
Titem * TryPop(const Tkey &key)
Remove an item by key if found.
void Push(Titem &new_item)
Add an item that may not exist.
const Titem * Find(const Tkey &key) const
Try to find an item by key.
Titem * Find(const Tkey &key)
Try to find an item by key.
int Count() const
Get the number of elements.
void Clear()
Clear all items.
Titem & Pop(const Tkey &key)
Remove an item by key that must exist.
Slot slots[CAPACITY]
Data storage (array of blobs).
static int CalcHash(const Titem &item)
Return hash for the given item modulo number of slots.
bool TryPop(Titem &item)
Remove an item if found.
int number_of_items
Item counter.
HashTableSlot< Titem > Slot
each slot contains pointer to the first item in the list, Titem contains pointer to the next item - G...
static int CalcHash(const Tkey &key)
Return hash for the given key modulo number of slots.
void Pop(Titem &item)
Remove an item that must exist.
TItem * Find(const Key &key)
Linear search for item with given key through the given blob.
bool Detach(TItem &item_to_remove)
Remove item from a slot.
const TItem * Find(const Key &key) const
Linear search for item with given key through the given blob.
void Attach(TItem &new_item)
Add new item to the slot.
TItem * Detach(const Key &key)
Remove and return item from a slot.
void Clear()
Clears the slot by simple forgetting its items.