75
This commit is contained in:
parent
37eb4540e9
commit
38aad5c108
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user