Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cHashTable.h
Go to the documentation of this file.
1 //
5 //
6 
7 #ifndef _INC_cHashTable_H
8 #define _INC_cHashTable_H
9 #ifndef NO_PRAGMA_ONCE
10 #pragma once
11 #endif
12 
13 #include "cArraySortRef.h"
14 #include "cBits.h"
15 #include "cUnitTestDecl.h"
16 
17 namespace Gray
18 {
19  class cHashIterator // inline
20  {
23  public:
26  public:
27  cHashIterator(ITERATE_t nBucket = 0, ITERATE_t jj = 0) noexcept
28  : m_i(nBucket)
29  , m_j(jj)
30  {
31  }
32  void SkipRemoved() noexcept
33  {
35  m_j--;
36  }
37  ITERATE_t get_ArrayNum() const noexcept
38  {
40  return m_i;
41  }
42  bool isValid() const noexcept
43  {
44  return(m_j >= 0);
45  }
46  };
47 
48  template<class _TYPEARRAY, class TYPE, typename TYPE_HASHCODE = HASHCODE_t, int TYPE_HASHBITS = 5 >
50  {
54 
55  public:
56  static const ITERATE_t k_HASH_ARRAY_QTY = _1BITMASK(TYPE_HASHBITS);
57  typedef cHashIterator iterator; // like STL.
59 
60  public:
61  int get_HashBits() const
62  {
63  return TYPE_HASHBITS;
64  }
66  {
67  return k_HASH_ARRAY_QTY;
68  }
69  ITERATE_t GetHashArray(TYPE_HASHCODE rid) const
70  {
72  return((ITERATE_t)(rid & (k_HASH_ARRAY_QTY - 1)));
73  }
75  {
77  return(m_aTable[iArray].GetSize());
78  }
79  iterator FindIForKey(TYPE_HASHCODE rid) const
80  {
81  ITERATE_t iBucket = GetHashArray(rid);
82  return(cHashIterator(iBucket, m_aTable[iBucket].FindIForKey(rid)));
83  }
84  TYPE_HASHCODE FindKeyFree(TYPE_HASHCODE rid) const
85  {
87  while (FindIForKey(rid).isValid()) // found it ?
88  {
89  rid++;
90  }
91  return rid;
92  }
93  bool DeleteKey(TYPE_HASHCODE rid)
94  {
96  return m_aTable[GetHashArray(rid)].RemoveKey(rid);
97  }
98  bool IsEmpty() const
99  {
100  for (ITERATE_t i = 0; i < k_HASH_ARRAY_QTY; i++)
101  {
102  if (!m_aTable[i].IsEmpty())
103  return false;
104  }
105  return true;
106  }
108  {
109  ITERATE_t iTotalCount = 0;
110  for (ITERATE_t i = 0; i < k_HASH_ARRAY_QTY; i++)
111  {
112  iTotalCount += m_aTable[i].GetSize();
113  }
114  return iTotalCount;
115  }
117  {
119  m_aTable[i.m_i].RemoveAt(i.m_j);
120  i.SkipRemoved();
121  }
122 
123  void RemoveAll()
124  {
125  for (ITERATE_t i = 0; i < k_HASH_ARRAY_QTY; i++)
126  {
127  this->m_aTable[i].RemoveAll();
128  }
129  }
130 
131  void Empty()
132  {
133  RemoveAll();
134  }
135 
136  UNITTEST_FRIEND(cHashTable);
137  };
138 
139  template<class TYPE, typename TYPE_HASHCODE = HASHCODE_t, int TYPE_HASHBITS = 5 >
140  class cHashTableStruct : public cHashTableT < cArraySortStructHash<TYPE, TYPE_HASHCODE>, TYPE, TYPE_HASHCODE, TYPE_HASHBITS >
141  {
144  public:
145  typedef cHashTableT< cArraySortStructHash<TYPE, TYPE_HASHCODE>, TYPE, TYPE_HASHCODE, TYPE_HASHBITS > SUPER_t;
146  typedef const TYPE& REF_t; // How to refer to this? value or ref or pointer?
147 
148  public:
149  const TYPE* FindArgForKey(TYPE_HASHCODE rid) const
150  {
151  ITERATE_t iBucket = this->GetHashArray(rid);
152  return this->m_aTable[iBucket].FindArgForKey(rid);
153  }
154  const TYPE& GetAtHash(const cHashIterator& i) const
155  {
157  ASSERT(IS_INDEX_GOOD_ARRAY(i.m_i, this->m_aTable));
158  return(this->m_aTable[i.m_i].ConstElementAt(i.m_j));
159  }
160  cHashIterator FindHash(TYPE_HASHCODE rid) const
161  {
162  ITERATE_t iBucket = this->GetHashArray(rid);
163  ITERATE_t index = this->m_aTable[iBucket].FindArgForKey(rid);
164  return cHashIterator(iBucket, index);
165  }
166  const TYPE& Add(REF_t rNew)
167  {
168  ITERATE_t iBucket = this->GetHashArray(rNew.get_HashCode());
169  ITERATE_t index = this->m_aTable[iBucket].Add(rNew);
170  return this->m_aTable[iBucket].GetAt(index);
171  }
173  {
174  // Add only new hash node. return index ONLY if existing hash node.
175  ITERATE_t iBucket = this->GetHashArray(rNew.get_HashCode());
176  COMPARE_t iCompareRes;
177  ITERATE_t index = this->m_aTable[iBucket].FindINear(rNew, iCompareRes);
178  if (iCompareRes == COMPARE_Equal)
179  {
180  return &this->m_aTable[iBucket].ElementAt(index); // special return that says it already was here.
181  }
182 
183  // not duplicate. must add
184  index = this->m_aTable[iBucket].AddPresorted(index, iCompareRes, rNew);
185  return nullptr; // special return that says i added it.
186  }
187  };
188 
189  template<class TYPE, typename TYPE_HASHCODE = HASHCODE_t, int TYPE_HASHBITS = 5 >
190  class cHashTableRef : public cHashTableT < cArraySortHash<TYPE, TYPE_HASHCODE>, TYPE, TYPE_HASHCODE, TYPE_HASHBITS >
191  {
194  protected:
196  public:
197  PTR_t FindArgForKey(TYPE_HASHCODE rid) const
198  {
199  ITERATE_t i = this->GetHashArray(rid);
200  return this->m_aTable[i].FindArgForKey(rid);
201  }
203  {
204  ASSERT(pNew != nullptr);
205  return this->m_aTable[this->GetHashArray(pNew->get_HashCode())].Add(pNew);
206  }
207  bool DeleteArg(TYPE* pObj)
208  {
209  if (pObj == nullptr)
210  return false;
211  return this->m_aTable[this->GetHashArray(pObj->get_HashCode())].RemoveArgKey(pObj);
212  }
213  PTR_t GetAtHash(const cHashIterator& i) const
214  {
216  ASSERT(IS_INDEX_GOOD_ARRAY(i.m_i, this->m_aTable));
217  return(this->m_aTable[i.m_i].ConstElementAt(i.m_j));
218  }
219 
220  PTR_t GetAt(TYPE_HASHCODE rid, ITERATE_t index) const
221  {
222  return(this->m_aTable[this->GetHashArray(rid)].ConstElementAt(index));
223  }
224  void DisposeAll()
225  {
227  for (ITERATE_t i = 0; i < this->k_HASH_ARRAY_QTY; i++)
228  {
229  this->m_aTable[i].DisposeAll();
230  }
231  }
232  };
233 
234  // Iterate through all members. iterator i;
235 #define FOR_HASH_TABLE(h,i) for ( ; i.m_i<h.k_HASH_ARRAY_QTY; i.m_i++ ) for ( i.m_j=0; i.m_j<h.m_aTable[i.m_i].GetSize(); i.m_j++ )
236 };
237 
238 #endif // _INC_CHASH_H
#define IS_INDEX_GOOD_ARRAY(i, a)
Definition: Index.h:38
#define IS_INDEX_GOOD(i, q)
cast the (likely) int to unsigned to check for negatives.
Definition: Index.h:35
#define TYPE
Definition: StrT.cpp:38
#define _1BITMASK(b)
default bitmask type = size_t. Use cBits::Mask1() for other type.
Definition: cBits.h:32
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define UNITTEST_FRIEND(n)
Define this in the class body to be unit tested. Allow the unit test to access private/protected stuf...
Definition: cUnitTestDecl.h:17
TYPE_PTR FindArgForKey(TYPE_KEY key1) const noexcept
Definition: cArraySort.h:455
bool RemoveArgKey(TYPE *pBase)
Definition: cArraySortRef.h:101
void DisposeAll()
Definition: cArraySortRef.h:30
ITERATE_t Add(TYPE_ARG pNew)
Definition: cArraySort.h:186
REF_t ConstElementAt(ITERATE_t nIndex) const
Definition: cArray.h:534
Definition: cHashTable.h:20
ITERATE_t m_i
array/Bucket number in the hash.
Definition: cHashTable.h:24
ITERATE_t m_j
element inside a array/Bucket.
Definition: cHashTable.h:25
void SkipRemoved() noexcept
Definition: cHashTable.h:32
ITERATE_t get_ArrayNum() const noexcept
Definition: cHashTable.h:37
cHashIterator(ITERATE_t nBucket=0, ITERATE_t jj=0) noexcept
Definition: cHashTable.h:27
bool isValid() const noexcept
Definition: cHashTable.h:42
Definition: cHashTable.h:191
void DisposeAll()
Definition: cHashTable.h:224
PTR_t GetAt(TYPE_HASHCODE rid, ITERATE_t index) const
Definition: cHashTable.h:220
PTR_t GetAtHash(const cHashIterator &i) const
Definition: cHashTable.h:213
PTR_t FindArgForKey(TYPE_HASHCODE rid) const
Definition: cHashTable.h:197
cRefPtr< TYPE > PTR_t
Definition: cHashTable.h:195
bool DeleteArg(TYPE *pObj)
Definition: cHashTable.h:207
ITERATE_t Add(TYPE *pNew)
Definition: cHashTable.h:202
Definition: cHashTable.h:141
const TYPE & REF_t
Definition: cHashTable.h:146
const TYPE * FindArgForKey(TYPE_HASHCODE rid) const
Definition: cHashTable.h:149
const TYPE & GetAtHash(const cHashIterator &i) const
Definition: cHashTable.h:154
cHashIterator FindHash(TYPE_HASHCODE rid) const
Definition: cHashTable.h:160
TYPE * AddSpecial(REF_t rNew)
Definition: cHashTable.h:172
const TYPE & Add(REF_t rNew)
Definition: cHashTable.h:166
cHashTableT< cArraySortStructHash< TYPE, TYPE_HASHCODE >, TYPE, TYPE_HASHCODE, TYPE_HASHBITS > SUPER_t
Definition: cHashTable.h:145
Definition: cHashTable.h:50
void RemoveAll()
Definition: cHashTable.h:123
TYPE_HASHCODE FindKeyFree(TYPE_HASHCODE rid) const
Definition: cHashTable.h:84
bool IsEmpty() const
Definition: cHashTable.h:98
ITERATE_t get_HashArrayQty() const
Definition: cHashTable.h:65
_TYPEARRAY m_aTable[k_HASH_ARRAY_QTY]
Definition: cHashTable.h:58
iterator FindIForKey(TYPE_HASHCODE rid) const
Definition: cHashTable.h:79
ITERATE_t get_TotalCount() const
Definition: cHashTable.h:107
ITERATE_t GetArraySize(ITERATE_t iArray) const
Definition: cHashTable.h:74
int get_HashBits() const
Definition: cHashTable.h:61
ITERATE_t GetHashArray(TYPE_HASHCODE rid) const
Definition: cHashTable.h:69
void Empty()
Definition: cHashTable.h:131
cHashIterator iterator
Definition: cHashTable.h:57
static const ITERATE_t k_HASH_ARRAY_QTY
Definition: cHashTable.h:56
bool DeleteKey(TYPE_HASHCODE rid)
Definition: cHashTable.h:93
void RemoveAt(iterator &i)
Definition: cHashTable.h:116
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
int COMPARE_t
result of compare. 0=same, 1=a>b, -1=a<b
Definition: cValT.h:17
int ITERATE_t
like size_t but signed
Definition: Index.h:28
@ COMPARE_Equal
VARCMP_EQ.
Definition: cValT.h:23
uint16 index
Definition: sample3.cpp:29