This commit is contained in:
Timerix22 2022-06-13 14:54:50 +03:00
parent 37eb4540e9
commit 38aad5c108
2 changed files with 121 additions and 75 deletions

View File

@ -1,13 +1,11 @@
#pragma once
#include "../base/base.h"
#define Autoarr2_NO_REZULT -1
template<typename T>
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 <value> inclusion
uint32 search(T& value);
uint32 search(T& value, uint32 fromIndex);
uint32 search(T& value, uint32 fromIndex, uint32 toIndex);
// using <cmpf> 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<typename T>
uint32 Autoarr2<T>::search(T& value, uint32 fromIndex, uint32 toIndex){
uint32 Autoarr2<T>::search(T& value, cmp_func_t cmpf, uint32 fromIndex, uint32 toIndex){
uint32 index=fromIndex;
for(; index<toIndex; index++)
if(value==get(index))
if(cmpf(value,get(index)))
return index;
return Autoarr2_NO_REZULT;
}
template<typename T>
uint32 Autoarr2<T>::search(T& value, uint32 fromIndex){
return search(value, fromIndex, length);
uint32 Autoarr2<T>::search(T& value, cmp_func_t cmpf, uint32 fromIndex){
return search(value, cmpf, fromIndex, length);
}
template<typename T>
uint32 Autoarr2<T>::search(T& value){
return search(value, 0, length);
uint32 Autoarr2<T>::search(T& value, cmp_func_t cmpf){
return search(value, cmpf, 0, length);
}

View File

@ -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
@ -18,18 +20,30 @@ static const HT_HEIGHT_T HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
template<typename TKey, typename TVal>
class Hashtable2{
Autoarr2<HT_HASH_T>* hashes;
Autoarr2<TKey>* keys;
Autoarr2<TVal>* values;
using cmp_func_t=bool (*)(TKey, TKey);
#if STORE_HASHES
Autoarr2<HT_HASH_T>** hashes;
#endif
cmp_func_t keyComparFunc;
Autoarr2<TKey>** keys;
Autoarr2<TVal>** 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<typename TKey, typename TVal>
Hashtable2<TKey, TVal>::Hashtable2(){
hein=_HT_HEIN_MIN;
HT_HEIGHT_T h=height();
hashes=new Autoarr2<HT_HASH_T>[h];
keys=new Autoarr2<TKey>[h];
values=new Autoarr2<TVal>[h];
for(HT_HEIGHT_T i=0; i<h; i++){
hashes[i]=Autoarr2<HT_HASH_T>(_HT_ARR_BL);
keys[i]=Autoarr2<TKey>(_HT_ARR_BL);
values[i]=Autoarr2<TVal>(_HT_ARR_BL);
_height=HT_HEIGHTS[hein];
#if STORE_HASHES
hashes=new Autoarr2<HT_HASH_T>*[_height];
#endif
keys=new Autoarr2<TKey>*[_height];
values=new Autoarr2<TVal>*[_height];
for(HT_HEIGHT_T i=0; i<_height; i++){
#if STORE_HASHES
hashes[i]=new Autoarr2<HT_HASH_T>(_HT_ARR_BL);
keyComparFunc=NULL;
#endif
keys[i]=new Autoarr2<TKey>(_HT_ARR_BL);
values[i]=new Autoarr2<TVal>(_HT_ARR_BL);
}
}
#if !STORE_HASHES
template<typename TKey, typename TVal>
Hashtable2<TKey, TVal>::Hashtable2(cmp_func_t _keyComparFunc) : Hashtable2() {
keyComparFunc=_keyComparFunc;
}
#endif
template<typename TKey, typename TVal>
Hashtable2<TKey, TVal>::~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<typename TKey, typename TVal>
void Hashtable2<TKey, TVal>::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<TKey>** newKeys=new Autoarr2<TKey>*[newHeight];
Autoarr2<TVal>** newValues=new Autoarr2<TVal>*[newHeight];
#if STORE_HASHES
Autoarr2<HT_HASH_T>** newHashes=new Autoarr2<HT_HASH_T>*[newHeight];
#endif
uint32 oldHeight=height();
hein++;
uint32 newHeight=height();
Autoarr2<HT_HASH_T>* newHashes=new Autoarr2<HT_HASH_T>[newHeight];
Autoarr2<TKey>* newKeys=new Autoarr2<TKey>[newHeight];
Autoarr2<TVal>* newValues=new Autoarr2<TVal>[newHeight];
for(HT_HEIGHT_T i=0; i<newHeight; i++){
newHashes[i]=Autoarr2<HT_HASH_T>(_HT_ARR_BL);
newKeys[i]=Autoarr2<TKey>(_HT_ARR_BL);
newValues[i]=Autoarr2<TVal>(_HT_ARR_BL);
newKeys[i]=new Autoarr2<TKey>(_HT_ARR_BL);
newValues[i]=new Autoarr2<TVal>(_HT_ARR_BL);
#if STORE_HASHES
newHashes[i]=new Autoarr2<HT_HASH_T>(_HT_ARR_BL);
#endif
}
for(HT_HEIGHT_T rowN=0; rowN<newHeight; rowN++){
Autoarr2<HT_HASH_T>* oldHashesRow= hashes+rowN;
Autoarr2<TKey>* oldKeysRow = keys +rowN;
Autoarr2<TVal>* oldValuesRow= values+rowN;
for(HT_HEIGHT_T rowN=0; rowN<_height; rowN++){
Autoarr2<TKey>* oldKeysRow=keys[rowN];
Autoarr2<TVal>* oldValuesRow=values[rowN];
#if STORE_HASHES
Autoarr2<HT_HASH_T>* 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<HT_HASH_T>* newHashesRow= newHashes+newRowN;
Autoarr2<TKey>* newKeysRow = newKeys +newRowN;
Autoarr2<TVal>* 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<typename TKey, typename TVal>
TVal* Hashtable2<TKey, TVal>::getptr(TKey key){
HT_HASH_T keyHash=HT_HASH(key);
HT_HEIGHT_T rowHeight=keyHash%height();
Autoarr2<HT_HASH_T>* 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<TVal>* valuesRow=values+rowHeight;
return valuesRow->getptr(index);
return values[rowN]->getptr(index);
}
template<typename TKey, typename TVal>
TVal Hashtable2<TKey, TVal>::get(TKey key){
}
template<typename TKey, typename TVal>
bool Hashtable2<TKey, TVal>::addOrSet(TKey key, TVal){
//expand
}
template<typename TKey, typename TVal>
bool Hashtable2<TKey, TVal>::remove(TKey){
}
template<typename TKey, typename TVal>
Hashtable2<TKey, TVal>::~Hashtable2(){
delete[] hashes;
delete[] keys;
delete[] values;
}