LoAdSG
simpleMultiHash.h
1#ifndef SIMPLEMULTIHASH_H
2#define SIMPLEMULTIHASH_H
3
4
5#include <math.h>
6#include <cstring>
7using namespace std;
8
9
16template<typename T>
18private:
19 T* _data;
21 size_t _capacity;
23 size_t _size;
24public:
25 SimpleVector(size_t initSize = 0):_capacity(initSize+10),_size(initSize){
26 // cout << "constructor" <<endl;
27 _data = new T[_capacity]();
28 // _data = (T*) calloc(_capacity,sizeof(T));
29 }
30
35 // cout << "destructor" <<endl;
36 delete [] _data;
37 // free(_data);
38 }
39
46 // cout << "copy constructor" <<endl;
47 _capacity = other._capacity;
48 _size=other._size;
49 _data = new T[_capacity]();
50 // _data = (T*) calloc(_capacity,sizeof(T));
51
52 memcpy(_data,other._data,_size*sizeof(T));
53 }
54
60 SimpleVector(SimpleVector&& other) noexcept
61 //: dataTableVector(std::exchange(other.dataTableVector, nullptr)) {} //TODO cpp14
62 {
63 // cout << "move constructor" <<endl;
64 _data=other._data;
65 other._data=nullptr;
66 _size = other._size;
67 _capacity =other._capacity;
68 }
76 {
77 cout << "copy assignment" <<endl;
78 if (this == &other) return *this;
79 return *this = SimpleVector(other);
80 // _capacity = other._capacity;
81 // _data = new T[_capacity];
82 // _size = other._size;
83 // return *this;
84 }
92 {
93 // cout << "move assignment" <<endl;
94 std::swap(_data, other._data);
95 _size = other._size;
96 _capacity = other._capacity;
97 return *this;
98 }
99
100 T& operator [] (size_t i){ return at(i); _data[i]; }
101 T& operator [] (size_t i) const { return at(i); _data[i]; }
109 T& at(size_t i) {if(i>=_size)throw out_of_range("Illegal vector access"); return _data[i];}
110 T& at(size_t i) const {if(i>=_size) {
111 cout << "Cap: " << _capacity << "Size: " << _size << ", Idx: " << i <<endl;
112 throw out_of_range("Illegal vector access2");
113 } return _data[i];}
114
115 void reserve(size_t newCapacity){
116 // realloc() // HACK it is not safe to use realloc with NEW
117 if(newCapacity <= _capacity) return;
118 T* oldData = _data;
119 _data = new T[newCapacity]();
120
121 // _data = (T*) calloc(newCapacity,sizeof(T));
122 memcpy(_data,oldData,_size * sizeof(T));
123 delete [] oldData;
124 //free(oldData);
125 _capacity = newCapacity;
126 }
127
128 void push_back(const T& value){
129 if(_size >= _capacity){reserve(_capacity<<1);} //TODO maybe other reserve strategy
130 _data[_size] = value;
131 _size++;
132 }
133
134 size_t size() const { return _size;}
135 size_t capacity() const { return _capacity;}
136 T* data() {return _data;}
137 T* data() const {return _data;}
138
139
140 T* begin(){return _data;};
141 T* begin() const {return _data;};
142 T* end(){return _data+_size;};
143 T* end() const {return _data+_size;};
144};
145
146
153template<typename T, typename D>
155 private:
156 D depth;
157 unsigned long hash(const T& point,const unsigned long tableSize) const {
158
159
160 unsigned long value = point.getIndex(0);
161 for (int d = 1; d < DimensionSparseGrid; ++d) {
162 value = value + point.getIndex(d) * PrimeNumbers::getPrimeForHash(d);
163 }
164
165 value = value + depth.at(0) * PrimeNumbers::getPrimeForHash(DimensionSparseGrid);
166 for (int d = 1; d < DimensionSparseGrid; d++)
167 value = value + depth.at(d) * PrimeNumbers::getPrimeForHash(DimensionSparseGrid + d);
168
169 return value % tableSize;
170
171 }
172
173 SimpleVector<unsigned long> firstTable; // 0 means not used. Contains the pos+1 in secondTable
174 SimpleVector<unsigned long> secondTable; // 0 means unused. 1 means end of entries for same hash. Contains pos+2 of next entry
175 SimpleVector<T> items;
176 //unsigned long (*hash)(const T& point,const unsigned long tableSize); // hash function
177
178
179 unsigned long getEndOfHashgroup(const unsigned long index) const{
180 unsigned long tmp = index;
181 while (secondTable[tmp]>1)
182 {
183 tmp = secondTable[tmp]-2;
184 }
185 return tmp;
186 }
187
197 bool checkIfItemInHashgroup(const unsigned long index,const T& item, unsigned long& outFoundPos) const {
198 size_t tmp = index;
199 while (secondTable[tmp]>=1)
200 {
201 if( items[tmp] == item ){
202 outFoundPos = tmp;
203 return true;
204 }
205 if(secondTable[tmp]==1) break;
206 tmp = secondTable[tmp]-2;
207 }
208 outFoundPos = tmp;
209 return false;
210 }
211
212 void checkIncreaseSecondTableSize() {
213 if(secondTable.capacity() == secondTable.size()){
214 secondTable.reserve(secondTable.size()*2);
215 items.reserve(items.size()*2);
216 }
217 }
218
219 public:
220
221 unsigned long size() const {
222 return secondTable.size();
223 }
231 SimpleMultiHash(D depth_ , const unsigned long firstTableSize = 100, const unsigned long secondTableInitSize=300):firstTable(firstTableSize)/*,secondTable(secondTableSize)*/{
232 depth=depth_;
233 secondTable.reserve(secondTableInitSize);
234 items.reserve(secondTableInitSize);
235 }
236
244 bool addPoint(const T& point){
245 unsigned long pos = hash(point,firstTable.size());
246 if(firstTable[pos]==0){
247 firstTable[pos]=secondTable.size()+1;
248 // secondTable.push_back(1);
249 // return true;
250 }else{
251 unsigned long lastPos;
252 if(checkIfItemInHashgroup(firstTable[pos]-1,point,lastPos)){
253 return false;
254 }
255 secondTable[lastPos] = secondTable.size()+2;
256 checkIncreaseSecondTableSize();
257 }
258 secondTable.push_back(1);
259 items.push_back(point);
260 return true;
261 }
262
263 // bool addPoint(const T& point, unsigned long& pos){
264 // size_t pos = hash(point,firstTable.size());
265 // if(firstTable[pos]==0){
266 // firstTable[pos]=secondTable.size()+1;
267 // // secondTable.push_back(1);
268 // // return true;
269 // }else{
270 // size_t lastPos;
271 // if(checkIfItemInHashgroup(firstTable[pos]-1,point,&lastPos)){
272 // return false;
273 // }
274 // secondTable[lastPos] = secondTable.size()+2;
275 // checkIncreaseSecondTableSize();
276 // }
277 // secondTable.push_back(1);
278 // items.push_back(point);
279 // pos = items.size()-1;
280 // return true;
281 // }
282
283 // bool addPointAtPos(const T& point, unsigned long pos){
284 // size_t pos = hash(point,firstTable.size());
285 // if(firstTable[pos]==0){
286 // firstTable[pos]=secondTable.size()+1;
287 // // secondTable.push_back(1);
288 // // return true;
289 // }else{
290 // size_t lastPos;
291 // if(checkIfItemInHashgroup(firstTable[pos]-1,point,&lastPos)){
292 // return false;
293 // }
294 // secondTable[lastPos] = secondTable.size()+2;
295 // checkIncreaseSecondTableSize();
296 // }
297 // secondTable.push_back(1);
298 // items.push_back(point);
299 // return true;
300 // }
306 void addPoint_Unique(const T& point){
307 unsigned long pos = hash(point,firstTable.size());
308 if(firstTable[pos]==0){
309 firstTable[pos]=secondTable.size()+1;
310 }else{
311 unsigned long lastPos = getEndOfHashgroup(firstTable[pos]-1);
312 secondTable[lastPos] = secondTable.size()+2;
313 checkIncreaseSecondTableSize();
314 }
315 secondTable.push_back(1);
316 items.push_back(point);
317 }
318
319 bool occupied(unsigned long& foundPos, const T& pointToSearch) const {
320 unsigned long pos = hash(pointToSearch,firstTable.size());
321 if(firstTable[pos]==0)
322 return false;
323 if(checkIfItemInHashgroup(firstTable[pos]-1,pointToSearch,foundPos)){
324 return true;
325 }
326 return false;
327
328 }
329
330 T getIndexOfTable(unsigned long i) const {
331 return items[i];
332 }
333
334 void print() const{
335 cout << "First Table: "<<endl;
336 for (auto &&i : firstTable)
337 {
338 cout << i << ", " <<endl;
339 }
340
341 // cout << "Second Table: "<<endl;
342 // for (auto &&i : secondTable)
343 // {
344 // cout << i << ", " <<endl;
345 // }
346 }
347
348 unsigned long getSizeOfHashgroup(const unsigned long index) const{
349 unsigned long tmp = index;
350 unsigned long size = 1;
351 while (secondTable[tmp]>1)
352 {
353 size++;
354 tmp = secondTable[tmp]-2;
355 }
356 return size;
357 }
358
359 long double getSTDOfHash(){
360 unsigned long sum =0;
361 for (auto &&i : firstTable)
362 {
363 if(i==0) continue;
364 unsigned long numOfItems = getSizeOfHashgroup(i-1);
365 sum += numOfItems;
366 }
367 long double mean = sum/firstTable.size();
368 long double std= 0;
369 // calc std
370 for (auto &&i : firstTable)
371 {
372 if(i==0) continue;
373 unsigned long numOfItems = getSizeOfHashgroup(i-1);
374 std += (numOfItems-mean)*(numOfItems-mean);
375 }
376 std /= firstTable.size() -1;
377 return sqrt(std);
378 }
379
380 long double getRedDragonHashQuality(){
381 long double res=0;
382 for (auto &&i : firstTable)
383 {
384 if(i==0) continue;
385 unsigned long numOfItems = getSizeOfHashgroup(i-1);
386 res += (numOfItems*(numOfItems+1)/2.0)/((double)(secondTable.size()+2*firstTable.size()-1));
387 }
388 return res;
389 }
390
391 void reorder(){
392
393 }
394};
395
396#endif // SIMPLEMULTIHASH_H
A simple multihash implementation. Is able to store multiple elements with the same hash.
Definition simpleMultiHash.h:154
bool addPoint(const T &point)
Will add the given point to the MultiHash. If the same point already exists it will not be added.
Definition simpleMultiHash.h:244
void addPoint_Unique(const T &point)
Will add the given point to the MultiHash. If the point already exists inside the Hashmap the behavio...
Definition simpleMultiHash.h:306
SimpleMultiHash(D depth_, const unsigned long firstTableSize=100, const unsigned long secondTableInitSize=300)
Construct a new Simple Multi Hash object.
Definition simpleMultiHash.h:231
bool checkIfItemInHashgroup(const unsigned long index, const T &item, unsigned long &outFoundPos) const
Will try to find the given item in the Hashgroup.
Definition simpleMultiHash.h:197
A simple vector implementation so as not to rely on the standard library implementation....
Definition simpleMultiHash.h:17
T & at(size_t i)
Array access with error checking.
Definition simpleMultiHash.h:109
SimpleVector(const SimpleVector &other)
copy constructor.
Definition simpleMultiHash.h:45
~SimpleVector()
Destroy the Simple Vector object.
Definition simpleMultiHash.h:34
SimpleVector & operator=(const SimpleVector &other)
copy assignment
Definition simpleMultiHash.h:75
SimpleVector(SimpleVector &&other) noexcept
move constructor
Definition simpleMultiHash.h:60
size_t _size
current number of elements in the Vector
Definition simpleMultiHash.h:23
size_t _capacity
reserved capacity for this vector. Always bigger or euqal to size
Definition simpleMultiHash.h:21
SimpleVector & operator=(SimpleVector &&other) noexcept
move assignment
Definition simpleMultiHash.h:91