diff --git a/src/Autoarr2/Autoarr2.hpp b/src/Autoarr2/Autoarr2.hpp index 67d307e..aa712e0 100644 --- a/src/Autoarr2/Autoarr2.hpp +++ b/src/Autoarr2/Autoarr2.hpp @@ -1,13 +1,11 @@ #pragma once -#include "../base/base.h" - #define Autoarr2_NO_REZULT -1 -template + +template class Autoarr2 { T** values; - public: uint16 blocks_count; uint16 block_length; @@ -22,10 +20,13 @@ public: T get(uint32 index); void set(uint32 index, T value); void add(T value); + // returns index of the first inclusion - uint32 search(T& value); - uint32 search(T& value, uint32 fromIndex); - uint32 search(T& value, uint32 fromIndex, uint32 toIndex); + // using to compare values + using cmp_func_t=bool (*)(T, T); + uint32 search(T& value, cmp_func_t cmpf, uint32 fromIndex, uint32 toIndex); + uint32 search(T& value, cmp_func_t cmpf, uint32 fromIndex); + uint32 search(T& value, cmp_func_t cmpf); }; @@ -93,22 +94,21 @@ create_block: length++; } - template -uint32 Autoarr2::search(T& value, uint32 fromIndex, uint32 toIndex){ +uint32 Autoarr2::search(T& value, cmp_func_t cmpf, uint32 fromIndex, uint32 toIndex){ uint32 index=fromIndex; for(; index -uint32 Autoarr2::search(T& value, uint32 fromIndex){ - return search(value, fromIndex, length); +uint32 Autoarr2::search(T& value, cmp_func_t cmpf, uint32 fromIndex){ + return search(value, cmpf, fromIndex, length); } template -uint32 Autoarr2::search(T& value){ - return search(value, 0, length); +uint32 Autoarr2::search(T& value, cmp_func_t cmpf){ + return search(value, cmpf, 0, length); } diff --git a/src/Hashtable2/Hashtable2.hpp b/src/Hashtable2/Hashtable2.hpp index e3502df..eaa2c0b 100644 --- a/src/Hashtable2/Hashtable2.hpp +++ b/src/Hashtable2/Hashtable2.hpp @@ -4,10 +4,12 @@ #include "../Autoarr2/Autoarr2.hpp" // amount of rows -typedef uint32 HT_HEIGHT_T; +typedef uint16 HT_HEIGHT_T; typedef uint32 HT_HASH_T; #define HT_HASH(K) hashb_sdbm32(K, sizeof(K)) +#define STORE_HASHES 1 + static const HT_HEIGHT_T HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521}; #define _HT_HEIN_MIN 0 #define _HT_HEIN_MAX 6 @@ -16,20 +18,32 @@ static const HT_HEIGHT_T HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521}; #define _HT_ARR_BL 8 -template +template class Hashtable2{ - Autoarr2* hashes; - Autoarr2* keys; - Autoarr2* values; + using cmp_func_t=bool (*)(TKey, TKey); + +#if STORE_HASHES + Autoarr2** hashes; + +#endif + cmp_func_t keyComparFunc; + Autoarr2** keys; + Autoarr2** values; uint8 hein; - + HT_HEIGHT_T _height; void expand(); - + bool uint32_compare(uint32& a, uint32& b) { return a==b; } +#if STORE_HASHES public: +#endif Hashtable2(); - virtual ~Hashtable2(); +#if !STORE_HASHES +public: + explicit Hashtable2(cmp_func_t _keyComparFunc); +#endif - HT_HEIGHT_T height(){ return HT_HEIGHTS[hein]; } + virtual ~Hashtable2(); + inline HT_HEIGHT_T height(){ return _height; } TVal* getptr(TKey key); TVal get(TKey key); bool addOrSet(TKey key, TVal); @@ -40,96 +54,128 @@ public: template Hashtable2::Hashtable2(){ hein=_HT_HEIN_MIN; - HT_HEIGHT_T h=height(); - hashes=new Autoarr2[h]; - keys=new Autoarr2[h]; - values=new Autoarr2[h]; - for(HT_HEIGHT_T i=0; i(_HT_ARR_BL); - keys[i]=Autoarr2(_HT_ARR_BL); - values[i]=Autoarr2(_HT_ARR_BL); + _height=HT_HEIGHTS[hein]; +#if STORE_HASHES + hashes=new Autoarr2*[_height]; +#endif + keys=new Autoarr2*[_height]; + values=new Autoarr2*[_height]; + for(HT_HEIGHT_T i=0; i<_height; i++){ +#if STORE_HASHES + hashes[i]=new Autoarr2(_HT_ARR_BL); + keyComparFunc=NULL; +#endif + keys[i]=new Autoarr2(_HT_ARR_BL); + values[i]=new Autoarr2(_HT_ARR_BL); } } +#if !STORE_HASHES +template +Hashtable2::Hashtable2(cmp_func_t _keyComparFunc) : Hashtable2() { + keyComparFunc=_keyComparFunc; +} +#endif + + +template +Hashtable2::~Hashtable2(){ + for(uint32 i=0; i< _height; i++){ + delete keys[i]; + delete values[i]; +#if STORE_HASHES + delete hashes[i]; +#endif + } + + delete keys; + delete values; +#if STORE_HASHES + delete hashes; +#endif +} + + template void Hashtable2::expand(){ if(hein>=_HT_HEIN_MAX) throw_id(ERR_MAXLENGTH); - if(hashes->length!=keys->length || hashes->length!=values->length) - throw_id(ERR_DESYNC); + uint32 newHeight=HT_HEIGHTS[++hein]; + Autoarr2** newKeys=new Autoarr2*[newHeight]; + Autoarr2** newValues=new Autoarr2*[newHeight]; +#if STORE_HASHES + Autoarr2** newHashes=new Autoarr2*[newHeight]; +#endif - uint32 oldHeight=height(); - hein++; - uint32 newHeight=height(); - Autoarr2* newHashes=new Autoarr2[newHeight]; - Autoarr2* newKeys=new Autoarr2[newHeight]; - Autoarr2* newValues=new Autoarr2[newHeight]; for(HT_HEIGHT_T i=0; i(_HT_ARR_BL); - newKeys[i]=Autoarr2(_HT_ARR_BL); - newValues[i]=Autoarr2(_HT_ARR_BL); + newKeys[i]=new Autoarr2(_HT_ARR_BL); + newValues[i]=new Autoarr2(_HT_ARR_BL); +#if STORE_HASHES + newHashes[i]=new Autoarr2(_HT_ARR_BL); +#endif } - for(HT_HEIGHT_T rowN=0; rowN* oldHashesRow= hashes+rowN; - Autoarr2* oldKeysRow = keys +rowN; - Autoarr2* oldValuesRow= values+rowN; + for(HT_HEIGHT_T rowN=0; rowN<_height; rowN++){ + Autoarr2* oldKeysRow=keys[rowN]; + Autoarr2* oldValuesRow=values[rowN]; +#if STORE_HASHES + Autoarr2* oldHashesRow=hashes[rowN]; +#endif - for(uint32 k=0; k < oldHashesRow->length; k++){ + for(uint32 k=0; k < oldKeysRow->length; k++){ + TKey currentKey=oldKeysRow->get(k); +#if STORE_HASHES HT_HASH_T currentHash=oldHashesRow->get(k); - HT_HEIGHT_T newRowN=currentHash%oldHeight; - - Autoarr2* newHashesRow= newHashes+newRowN; - Autoarr2* newKeysRow = newKeys +newRowN; - Autoarr2* newValuesRow= newValues+newRowN; - - newHashesRow->add(currentHash); - newKeysRow->add(oldKeysRow->get(k)); - newValuesRow->add(oldValuesRow->get(k)); +#else + HT_HASH_T currentHash=HT_HASH(currentKey); +#endif + HT_HEIGHT_T newRowN=currentHash%newHeight; +#if STORE_HASHES + newHashes[newRowN]->add(currentHash); +#endif + newKeys[newRowN]->add(currentKey); + newValues[newRowN]->add(values[rowN]->get(k)); } - //delete oldHashesRow; - //delete oldKeysRow; - //delete oldValuesRow; } - delete[] hashes; - delete[] keys; - delete[] values; - hashes=newHashes; + ~Hashtable2(); + _height=newHeight; keys=newKeys; values=newValues; +#if STORE_HASHES + hashes=newHashes; +#endif } + template TVal* Hashtable2::getptr(TKey key){ HT_HASH_T keyHash=HT_HASH(key); - HT_HEIGHT_T rowHeight=keyHash%height(); - Autoarr2* hashesRow=hashes+rowHeight; - uint32 index=hashesRow->search(keyHash); + HT_HEIGHT_T rowN=keyHash%_height; +#if STORE_HASHES + uint32 index=hashes[rowN]->search(keyHash, uint32_compare); +#else + uint32 index=keys[rowN]->search(key, keyComparFunc); +#endif if(index==Autoarr2_NO_REZULT) return NULL; - Autoarr2* valuesRow=values+rowHeight; - return valuesRow->getptr(index); + return values[rowN]->getptr(index); } + template TVal Hashtable2::get(TKey key){ } + template bool Hashtable2::addOrSet(TKey key, TVal){ //expand } + template bool Hashtable2::remove(TKey){ } - -template -Hashtable2::~Hashtable2(){ - delete[] hashes; - delete[] keys; - delete[] values; -}