15 #include "../core/math_func.hpp"
17 template <
class Titem_>
20 typedef typename Titem_::Key Key;
33 inline const Titem_ *
Find(
const Key &key)
const
35 for (
const Titem_ *pItem = m_pFirst; pItem != NULL; pItem = pItem->GetHashNext()) {
36 if (pItem->GetKey() == key) {
45 inline Titem_ *
Find(
const Key &key)
47 for (Titem_ *pItem = m_pFirst; pItem != NULL; pItem = pItem->GetHashNext()) {
48 if (pItem->GetKey() == key) {
59 assert(new_item.GetHashNext() == NULL);
60 new_item.SetHashNext(m_pFirst);
65 inline bool Detach(Titem_ &item_to_remove)
67 if (m_pFirst == &item_to_remove) {
68 m_pFirst = item_to_remove.GetHashNext();
69 item_to_remove.SetHashNext(NULL);
72 Titem_ *pItem = m_pFirst;
77 Titem_ *pNextItem = pItem->GetHashNext();
78 if (pNextItem == &item_to_remove)
break;
81 pItem->SetHashNext(item_to_remove.GetHashNext());
82 item_to_remove.SetHashNext(NULL);
87 inline Titem_ *
Detach(
const Key &key)
90 if (m_pFirst == NULL) {
94 if (m_pFirst->GetKey() == key) {
95 Titem_ &ret_item = *m_pFirst;
96 m_pFirst = m_pFirst->GetHashNext();
97 ret_item.SetHashNext(NULL);
101 Titem_ *pPrev = m_pFirst;
102 for (Titem_ *pItem = m_pFirst->GetHashNext(); pItem != NULL; pPrev = pItem, pItem = pItem->GetHashNext()) {
103 if (pItem->GetKey() == key) {
105 pPrev->SetHashNext(pItem->GetHashNext());
106 pItem->SetHashNext(NULL);
136 template <
class Titem_,
int Thash_bits_>
139 typedef Titem_ Titem;
140 typedef typename Titem_::Key Tkey;
141 static const int Thash_bits = Thash_bits_;
142 static const int Tcapacity = 1 << Thash_bits;
151 Slot m_slots[Tcapacity];
164 int32 hash = key.CalcHash();
165 if ((8 * Thash_bits) < 32) hash ^= hash >> (
min(8 * Thash_bits, 31));
166 if ((4 * Thash_bits) < 32) hash ^= hash >> (
min(4 * Thash_bits, 31));
167 if ((2 * Thash_bits) < 32) hash ^= hash >> (
min(2 * Thash_bits, 31));
168 if ((1 * Thash_bits) < 32) hash ^= hash >> (
min(1 * Thash_bits, 31));
169 hash &= (1 << Thash_bits) - 1;
189 for (
int i = 0; i < Tcapacity; i++) m_slots[i].
Clear();
193 const Titem_ *
Find(
const Tkey &key)
const
196 const Slot &slot = m_slots[hash];
197 const Titem_ *item = slot.
Find(key);
205 Slot &slot = m_slots[hash];
206 Titem_ *item = slot.
Find(key);
214 Slot &slot = m_slots[hash];
215 Titem_ *item = slot.
Detach(key);
223 Titem_&
Pop(
const Tkey &key)
225 Titem_ *item =
TryPop(key);
226 assert(item != NULL);
233 const Tkey &key = item.GetKey();
235 Slot &slot = m_slots[hash];
236 bool ret = slot.
Detach(item);
254 Slot &slot = m_slots[hash];
255 assert(slot.
Find(new_item.GetKey()) == NULL);