Hashtable2 with many bugs
This commit is contained in:
parent
893a24eeb3
commit
378277450b
8
.idea/customTargets.xml
Normal file
8
.idea/customTargets.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CLionExternalBuildManager">
|
||||||
|
<target id="67054554-5381-4cd7-a829-42719335ecb2" name="test" defaultType="MAKE">
|
||||||
|
<configuration id="5bcf7815-3a13-43ba-8bab-ca1ed444708d" name="test" />
|
||||||
|
</target>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define Autoarr2_NO_REZULT -1
|
#define Autoarr2_NO_REZULT (uint32)-1
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -20,13 +20,16 @@ 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);
|
||||||
|
void remove(uint32 index);
|
||||||
|
|
||||||
// returns index of the first <value> inclusion
|
// returns index of the first <value> inclusion
|
||||||
// using <cmpf> to compare values
|
// using <cmpf> to compare values
|
||||||
using cmp_func_t=bool (*)(T, T);
|
template<class cmp_func_lambda>
|
||||||
uint32 search(T& value, cmp_func_t cmpf, uint32 fromIndex, uint32 toIndex);
|
uint32 search(T& value, cmp_func_lambda cmpf, uint32 fromIndex, uint32 toIndex);
|
||||||
uint32 search(T& value, cmp_func_t cmpf, uint32 fromIndex);
|
template<class cmp_func_lambda>
|
||||||
uint32 search(T& value, cmp_func_t cmpf);
|
uint32 search(T& value, cmp_func_lambda cmpf, uint32 fromIndex);
|
||||||
|
template<class cmp_func_lambda>
|
||||||
|
uint32 search(T& value, cmp_func_lambda cmpf);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -73,7 +76,6 @@ void Autoarr2<T>::set(uint32 index, T value) {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void Autoarr2<T>::add(T value) {
|
void Autoarr2<T>::add(T value) {
|
||||||
if(!values){
|
if(!values){
|
||||||
//values=(T**)malloc(sizeof(T*));
|
|
||||||
values=new T*[1];
|
values=new T*[1];
|
||||||
goto create_block;
|
goto create_block;
|
||||||
}
|
}
|
||||||
@ -83,9 +85,9 @@ create_block:
|
|||||||
T** new_values=new T*[blocks_count+1];
|
T** new_values=new T*[blocks_count+1];
|
||||||
for(uint32 i=0;i<blocks_count;i++)
|
for(uint32 i=0;i<blocks_count;i++)
|
||||||
new_values[i]=values[i];
|
new_values[i]=values[i];
|
||||||
|
new_values[blocks_count]=new T[max_block_length];
|
||||||
delete[] values;
|
delete[] values;
|
||||||
values=new_values;
|
values=new_values;
|
||||||
values[blocks_count]=new T[max_block_length];
|
|
||||||
blocks_count++;
|
blocks_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +97,8 @@ create_block:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
uint32 Autoarr2<T>::search(T& value, cmp_func_t cmpf, uint32 fromIndex, uint32 toIndex){
|
template<class cmp_func_lambda>
|
||||||
|
uint32 Autoarr2<T>::search(T& value, cmp_func_lambda cmpf, uint32 fromIndex, uint32 toIndex){
|
||||||
uint32 index=fromIndex;
|
uint32 index=fromIndex;
|
||||||
for(; index<toIndex; index++)
|
for(; index<toIndex; index++)
|
||||||
if(cmpf(value,get(index)))
|
if(cmpf(value,get(index)))
|
||||||
@ -104,11 +107,18 @@ uint32 Autoarr2<T>::search(T& value, cmp_func_t cmpf, uint32 fromIndex, uint32 t
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
uint32 Autoarr2<T>::search(T& value, cmp_func_t cmpf, uint32 fromIndex){
|
template<class cmp_func_lambda>
|
||||||
|
uint32 Autoarr2<T>::search(T& value, cmp_func_lambda cmpf, uint32 fromIndex){
|
||||||
return search(value, cmpf, fromIndex, length);
|
return search(value, cmpf, fromIndex, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
uint32 Autoarr2<T>::search(T& value, cmp_func_t cmpf){
|
template<class cmp_func_lambda>
|
||||||
|
uint32 Autoarr2<T>::search(T& value, cmp_func_lambda cmpf){
|
||||||
return search(value, cmpf, 0, length);
|
return search(value, cmpf, 0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Autoarr2<T>::remove(uint32 index){
|
||||||
|
throw_id(ERR_NOTIMPLEMENTED);
|
||||||
|
}
|
||||||
@ -4,11 +4,10 @@
|
|||||||
#include "../Autoarr2/Autoarr2.hpp"
|
#include "../Autoarr2/Autoarr2.hpp"
|
||||||
|
|
||||||
// amount of rows
|
// amount of rows
|
||||||
typedef uint16 HT_HEIGHT_T;
|
typedef uint32 HT_HEIGHT_T;
|
||||||
typedef uint32 HT_HASH_T;
|
typedef uint32 HT_HASH_T;
|
||||||
#define HT_HASH(K) hashb_sdbm32(K, sizeof(K))
|
|
||||||
|
|
||||||
#define STORE_HASHES 1
|
#define STORE_HASHES 0
|
||||||
|
|
||||||
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
|
||||||
@ -20,162 +19,187 @@ static const HT_HEIGHT_T HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
|
|||||||
|
|
||||||
template<typename TKey, typename TVal>
|
template<typename TKey, typename TVal>
|
||||||
class Hashtable2{
|
class Hashtable2{
|
||||||
using cmp_func_t=bool (*)(TKey, TKey);
|
// internal types
|
||||||
|
struct KeyValue{
|
||||||
|
TKey key;
|
||||||
|
TVal value;
|
||||||
#if STORE_HASHES
|
#if STORE_HASHES
|
||||||
Autoarr2<HT_HASH_T>** hashes;
|
HT_HASH_T hash;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
cmp_func_t keyComparFunc;
|
};
|
||||||
Autoarr2<TKey>** keys;
|
using HashKeyFunc_t=HT_HASH_T (*)(TKey);
|
||||||
Autoarr2<TVal>** values;
|
using KeyCmpFunc_t=bool (*)(TKey, TKey);
|
||||||
|
|
||||||
|
// fields
|
||||||
|
Autoarr2<KeyValue>** rows;
|
||||||
|
|
||||||
|
HashKeyFunc_t hashKeyFunc;
|
||||||
|
#if !STORE_HASHES
|
||||||
|
KeyCmpFunc_t keyComparFunc;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
HT_HEIGHT_T height;
|
||||||
|
private:
|
||||||
uint8 hein;
|
uint8 hein;
|
||||||
HT_HEIGHT_T _height;
|
|
||||||
void expand();
|
// constructors
|
||||||
bool uint32_compare(uint32& a, uint32& b) { return a==b; }
|
|
||||||
#if STORE_HASHES
|
#if STORE_HASHES
|
||||||
public:
|
public:
|
||||||
#endif
|
#endif
|
||||||
Hashtable2();
|
Hashtable2(HashKeyFunc_t _hashKeyFunc);
|
||||||
#if !STORE_HASHES
|
#if !STORE_HASHES
|
||||||
public:
|
public:
|
||||||
explicit Hashtable2(cmp_func_t _keyComparFunc);
|
explicit Hashtable2(HashKeyFunc_t _hashKeyFunc, KeyCmpFunc_t _keyComparFunc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// methods
|
||||||
|
private:
|
||||||
|
void free_rows();
|
||||||
|
TVal* getptr(TKey key, HT_HASH_T& keyHash, HT_HEIGHT_T& rowN);
|
||||||
|
void expand();
|
||||||
|
void add(TKey& key, TVal& value, HT_HASH_T keyHash, HT_HEIGHT_T rowN);
|
||||||
|
|
||||||
|
public:
|
||||||
virtual ~Hashtable2();
|
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 tryGet(TKey key, TVal* output);
|
||||||
bool remove(TKey);
|
void add(TKey key, TVal value);
|
||||||
|
void addOrSet(TKey key, TVal value);
|
||||||
|
void remove(TKey key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename TKey, typename TVal>
|
template<typename TKey, typename TVal>
|
||||||
Hashtable2<TKey, TVal>::Hashtable2(){
|
Hashtable2<TKey, TVal>::Hashtable2(HashKeyFunc_t _hashKeyFunc){
|
||||||
|
hashKeyFunc=_hashKeyFunc;
|
||||||
hein=_HT_HEIN_MIN;
|
hein=_HT_HEIN_MIN;
|
||||||
_height=HT_HEIGHTS[hein];
|
height=HT_HEIGHTS[hein];
|
||||||
#if STORE_HASHES
|
rows=new Autoarr2<KeyValue>*[height];
|
||||||
hashes=new Autoarr2<HT_HASH_T>*[_height];
|
for(HT_HEIGHT_T i=0; i<height; i++)
|
||||||
#endif
|
rows[i]=new Autoarr2<KeyValue>(_HT_ARR_BL);
|
||||||
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
|
#if !STORE_HASHES
|
||||||
template<typename TKey, typename TVal>
|
template<typename TKey, typename TVal>
|
||||||
Hashtable2<TKey, TVal>::Hashtable2(cmp_func_t _keyComparFunc) : Hashtable2() {
|
Hashtable2<TKey, TVal>::Hashtable2(HashKeyFunc_t _hashKeyFunc, KeyCmpFunc_t _keyComparFunc) : Hashtable2(_hashKeyFunc) {
|
||||||
keyComparFunc=_keyComparFunc;
|
keyComparFunc=_keyComparFunc;
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
template<typename TKey, typename TVal>
|
||||||
delete values;
|
void Hashtable2<TKey, TVal>::free_rows(){
|
||||||
#if STORE_HASHES
|
for(uint32 i=0; i< height; i++)
|
||||||
delete hashes;
|
delete rows[i];
|
||||||
#endif
|
delete[] rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename TKey, typename TVal>
|
template<typename TKey, typename TVal>
|
||||||
void Hashtable2<TKey, TVal>::expand(){
|
Hashtable2<TKey, TVal>::~Hashtable2() { free_rows(); }
|
||||||
if(hein>=_HT_HEIN_MAX)
|
|
||||||
throw_id(ERR_MAXLENGTH);
|
|
||||||
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
|
|
||||||
|
|
||||||
for(HT_HEIGHT_T i=0; i<newHeight; i++){
|
|
||||||
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<_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 < oldKeysRow->length; k++){
|
|
||||||
TKey currentKey=oldKeysRow->get(k);
|
|
||||||
#if STORE_HASHES
|
|
||||||
HT_HASH_T currentHash=oldHashesRow->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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Hashtable2();
|
|
||||||
_height=newHeight;
|
|
||||||
keys=newKeys;
|
|
||||||
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_HEIGHT_T& rowN){
|
||||||
HT_HASH_T keyHash=HT_HASH(key);
|
keyHash=hashKeyFunc(key);
|
||||||
HT_HEIGHT_T rowN=keyHash%_height;
|
rowN=keyHash%height;
|
||||||
|
KeyValue kv;
|
||||||
#if STORE_HASHES
|
#if STORE_HASHES
|
||||||
uint32 index=hashes[rowN]->search(keyHash, uint32_compare);
|
kv.hash=keyHash;
|
||||||
|
uint32 index=rows[rowN]->search(kv, [](KeyValue kv0, KeyValue kv1) { return kv0.hash==kv1.hash; });
|
||||||
#else
|
#else
|
||||||
uint32 index=keys[rowN]->search(key, keyComparFunc);
|
kv.key=key;
|
||||||
|
uint32 index=rows[rowN]->search(kv, [this](KeyValue kv0, KeyValue kv1) { return this->keyComparFunc(kv0.key, kv1.key); });
|
||||||
#endif
|
#endif
|
||||||
if(index==Autoarr2_NO_REZULT)
|
if(index==Autoarr2_NO_REZULT)
|
||||||
return NULL;
|
return NULL;
|
||||||
return values[rowN]->getptr(index);
|
return &(rows[rowN]->getptr(index))->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename TKey, typename TVal>
|
||||||
|
TVal* Hashtable2<TKey, TVal>::getptr(TKey key){
|
||||||
|
HT_HASH_T keyHash;
|
||||||
|
HT_HEIGHT_T rowN;
|
||||||
|
return getptr(key, keyHash, rowN);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename TKey, typename TVal>
|
template<typename TKey, typename TVal>
|
||||||
TVal Hashtable2<TKey, TVal>::get(TKey key){
|
TVal Hashtable2<TKey, TVal>::get(TKey key){
|
||||||
|
TVal* ptr=getptr(key);
|
||||||
|
if(!ptr)
|
||||||
|
throw_id(ERR_KEYNOTFOUND);
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TKey, typename TVal>
|
||||||
|
bool Hashtable2<TKey, TVal>::tryGet(TKey key, TVal* output){
|
||||||
|
TVal* ptr=getptr(key);
|
||||||
|
if(!ptr)
|
||||||
|
return false;
|
||||||
|
*output=*ptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TKey, typename TVal>
|
||||||
|
void Hashtable2<TKey, TVal>::expand(){ printf("expand\n"); fflush(stdout);
|
||||||
|
if(hein>=_HT_HEIN_MAX)
|
||||||
|
throw_id(ERR_MAXLENGTH);
|
||||||
|
|
||||||
|
uint32 newHeight=HT_HEIGHTS[++hein];
|
||||||
|
Autoarr2<KeyValue>** newRows=new Autoarr2<KeyValue>*[newHeight];
|
||||||
|
for(HT_HEIGHT_T i=0; i<newHeight; i++)
|
||||||
|
newRows[i]=new Autoarr2<KeyValue>(_HT_ARR_BL);
|
||||||
|
|
||||||
|
for(HT_HEIGHT_T oldRowN=0; oldRowN<height; oldRowN++)
|
||||||
|
for(uint32 k=0; k < rows[oldRowN]->length; k++){
|
||||||
|
KeyValue kv=rows[oldRowN]->get(k);
|
||||||
|
#if STORE_HASHES
|
||||||
|
HT_HEIGHT_T newRowN=kv.hash%newHeight;
|
||||||
|
#else
|
||||||
|
HT_HEIGHT_T newRowN=hashKeyFunc(kv.key)%newHeight;
|
||||||
|
#endif
|
||||||
|
newRows[newRowN]->add(kv);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_rows();
|
||||||
|
height=newHeight;
|
||||||
|
rows=newRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TKey, typename TVal>
|
||||||
|
void Hashtable2<TKey, TVal>::add(TKey& key, TVal& value, HT_HASH_T keyHash, HT_HEIGHT_T rowN){ printf("add\n"); fflush(stdout);
|
||||||
|
Autoarr2<KeyValue>* row=rows[rowN];
|
||||||
|
if(row->length == _HT_ARR_BC*_HT_ARR_BL)
|
||||||
|
expand();
|
||||||
|
KeyValue kv;
|
||||||
|
kv.key=key;
|
||||||
|
kv.value=value;
|
||||||
|
#if STORE_HASHES
|
||||||
|
kv.hash=keyHash;
|
||||||
|
#endif
|
||||||
|
row->add(kv);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TKey, typename TVal>
|
||||||
|
void Hashtable2<TKey, TVal>::add(TKey key, TVal value){
|
||||||
|
HT_HASH_T keyHash=hashKeyFunc(key);
|
||||||
|
HT_HEIGHT_T rowN=keyHash%height;
|
||||||
|
add(key, value, keyHash, rowN);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TKey, typename TVal>
|
||||||
|
void Hashtable2<TKey, TVal>::addOrSet(TKey key, TVal value){
|
||||||
|
HT_HASH_T keyHash;
|
||||||
|
HT_HEIGHT_T rowN;
|
||||||
|
TVal* valptr=getptr(key, keyHash, rowN);
|
||||||
|
if(valptr) *valptr=value;
|
||||||
|
else add(key, value, keyHash, rowN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename TKey, typename TVal>
|
template<typename TKey, typename TVal>
|
||||||
bool Hashtable2<TKey, TVal>::addOrSet(TKey key, TVal){
|
void Hashtable2<TKey, TVal>::remove(TKey key){
|
||||||
//expand
|
throw_id(ERR_NOTIMPLEMENTED);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename TKey, typename TVal>
|
|
||||||
bool Hashtable2<TKey, TVal>::remove(TKey){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ char* errname(ErrorId err){
|
|||||||
case ERR_NOTIMPLEMENTED: return "ERR_NOTIMPLEMENTED";
|
case ERR_NOTIMPLEMENTED: return "ERR_NOTIMPLEMENTED";
|
||||||
case ERR_NULLPTR: return "ERR_NULLPTR";
|
case ERR_NULLPTR: return "ERR_NULLPTR";
|
||||||
case ERR_ENDOFSTR: return "ERR_ENDOFSTR";
|
case ERR_ENDOFSTR: return "ERR_ENDOFSTR";
|
||||||
case ERR_DESYNC: return "ERR_DESYNC";
|
case ERR_KEYNOTFOUND: return "ERR_KEYNOTFOUND";
|
||||||
default: return "UNKNOWN_ERROR";
|
default: return "UNKNOWN_ERROR";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ typedef enum ErrorId {
|
|||||||
SUCCESS, // not an error
|
SUCCESS, // not an error
|
||||||
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
|
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
|
||||||
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
|
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
|
||||||
ERR_DESYNC
|
ERR_KEYNOTFOUND
|
||||||
} ErrorId;
|
} ErrorId;
|
||||||
|
|
||||||
char* errname(ErrorId err);
|
char* errname(ErrorId err);
|
||||||
@ -51,10 +51,10 @@ char* __unknownErr( );
|
|||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
#define throw_id(E) __EXIT(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__)))
|
#define throw_id(E) __EXIT(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__)))
|
||||||
#define throw_msg(E) __EXIT(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__)))
|
#define throw_msg(E) __EXIT(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__)))
|
||||||
|
#else
|
||||||
|
#define throw(E) __EXIT(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__)))
|
||||||
|
#define safethrow(E, FREEMEM) { FREEMEM; __RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); }
|
||||||
#endif
|
#endif
|
||||||
#define throw(E) __EXIT(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__)))
|
|
||||||
#define safethrow(E, FREEMEM) { FREEMEM; __RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); }
|
|
||||||
|
|
||||||
|
|
||||||
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){\
|
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){\
|
||||||
freeMem;\
|
freeMem;\
|
||||||
|
|||||||
@ -4,12 +4,12 @@ void test_all(){
|
|||||||
// test_string();
|
// test_string();
|
||||||
// test_safethrow();
|
// test_safethrow();
|
||||||
// test_searchtree();
|
// test_searchtree();
|
||||||
test_autoarr();
|
// test_autoarr();
|
||||||
test_autoarr2();
|
// test_autoarr2();
|
||||||
// test_hash_functions();
|
// test_hash_functions();
|
||||||
test_hashtable();
|
// test_hashtable();
|
||||||
|
// test_dtsod();
|
||||||
test_hashtable2();
|
test_hashtable2();
|
||||||
//test_dtsod();
|
|
||||||
printf("\e[96m--------------------------------------\e[0m\n");
|
printf("\e[96m--------------------------------------\e[0m\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,58 +1,65 @@
|
|||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "../src/Hashtable2/Hashtable2.hpp"
|
#include "../src/Hashtable2/Hashtable2.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#define TKey char*
|
#define TKey std::shared_ptr<char>
|
||||||
#define TVal uint64
|
#define TVal uint64
|
||||||
#define HT_TYPE Hashtable2<TKey, TVal>
|
#define HT_TYPE Hashtable2<TKey, TVal>
|
||||||
#define HT_TYPE_NAME "Hashtable2<char*, uint64>"
|
#define HT_TYPE_NAME "Hashtable2<std::shared_ptr<char*>, uint64>"
|
||||||
|
|
||||||
void print_hashtable(HT_TYPE* ht){
|
void print_hashtable(HT_TYPE* ht){
|
||||||
printf("\e[94m" HT_TYPE_NAME ": "
|
printf("\e[94m" HT_TYPE_NAME ": "
|
||||||
IFWIN("%llu", "%lu")
|
IFWIN("%llu", "%lu")
|
||||||
"\n height: %u\n",
|
"\n height: %u\n",
|
||||||
sizeof(HT_TYPE),
|
sizeof(HT_TYPE),
|
||||||
ht->height());
|
ht->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* genkey(uint32 i){
|
std::shared_ptr<char> genkey(uint32 i){
|
||||||
char* key=new char[16];
|
char* key=new char[24];
|
||||||
IFMSC(
|
IFMSC(
|
||||||
sprintf_s(key,16,"key_%u",i),
|
sprintf_s(key,24,"key_%u",i),
|
||||||
sprintf(key,"key_%u",i)
|
sprintf(key,"key_%u",i)
|
||||||
);
|
);
|
||||||
return key;
|
dbg(i);
|
||||||
|
return std::shared_ptr<char>(key, [](char* s){ delete[] s;});
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill(HT_TYPE* ht){
|
void fill(HT_TYPE* ht){
|
||||||
//for(uint32 i=0;i<100000;i++)
|
for(uint32 i=0;i<251;i++)
|
||||||
// ht->add(genkey(i),Uni(UInt64,i));
|
ht->add(genkey(i), 555666);
|
||||||
|
print_hashtable(ht);
|
||||||
}
|
}
|
||||||
|
|
||||||
TVal gett(HT_TYPE* ht){
|
TVal gett(HT_TYPE* ht){
|
||||||
TVal u;
|
TVal u;
|
||||||
for(uint32 i=0;i<100000;i++){
|
for(uint32 i=0;i<1000;i++){
|
||||||
TKey key=genkey(i);
|
TKey key=genkey(i);
|
||||||
//u=ht->get(key);
|
u=ht->get(key);
|
||||||
delete[] key;
|
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_hashtable2(){
|
void test_hashtable2(){
|
||||||
optime("test_hashtable2",1,({
|
//optime("test_hashtable2",1,({
|
||||||
printf("\e[96m-----------[test_hashtable2]-----------\n");
|
printf("\e[96m-----------[test_hashtable2]-----------\n");
|
||||||
#if STORE_HASHES
|
#if STORE_HASHES
|
||||||
HT_TYPE* ht=new HT_TYPE();
|
HT_TYPE* ht=new HT_TYPE(
|
||||||
|
[](TKey k) { return hashs(hash_sdbm32,k.get()); });
|
||||||
#else
|
#else
|
||||||
HT_TYPE* ht=new HT_TYPE(cptr_compare);
|
HT_TYPE* ht=new HT_TYPE(
|
||||||
|
[](TKey k) { return hashs(hash_sdbm32,k.get()); },
|
||||||
|
[](TKey k0, TKey k1) { return cptr_compare(k0.get(), k1.get()); });
|
||||||
#endif
|
#endif
|
||||||
printf("\e[92m" HT_TYPE_NAME " created\n");
|
printf("\e[92mhashtable created\n");
|
||||||
print_hashtable(ht);
|
print_hashtable(ht);
|
||||||
optime("fill",1,fill(ht));
|
optime("fill",1,fill(ht));
|
||||||
optime("get",1,gett(ht));
|
// TVal r;
|
||||||
print_hashtable(ht);
|
// optime("get",1,r=gett(ht));
|
||||||
|
// dbg((uint32)r);
|
||||||
|
// print_hashtable(ht);
|
||||||
delete ht;
|
delete ht;
|
||||||
printf("\e[92m" HT_TYPE_NAME " deleted\n");
|
printf("\e[92mhashtable deleted\n");
|
||||||
}));
|
//}));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user