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