diff --git a/.idea/customTargets.xml b/.idea/customTargets.xml
new file mode 100644
index 0000000..4b31099
--- /dev/null
+++ b/.idea/customTargets.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Autoarr2/Autoarr2.hpp b/src/Autoarr2/Autoarr2.hpp
index aa712e0..ae3e39f 100644
--- a/src/Autoarr2/Autoarr2.hpp
+++ b/src/Autoarr2/Autoarr2.hpp
@@ -1,6 +1,6 @@
#pragma once
-#define Autoarr2_NO_REZULT -1
+#define Autoarr2_NO_REZULT (uint32)-1
template
@@ -20,13 +20,16 @@ public:
T get(uint32 index);
void set(uint32 index, T value);
void add(T value);
+ void remove(uint32 index);
// returns index of the first inclusion
// 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);
+ template
+ uint32 search(T& value, cmp_func_lambda cmpf, uint32 fromIndex, uint32 toIndex);
+ template
+ uint32 search(T& value, cmp_func_lambda cmpf, uint32 fromIndex);
+ template
+ uint32 search(T& value, cmp_func_lambda cmpf);
};
@@ -49,7 +52,7 @@ Autoarr2::Autoarr2(uint16 _max_block_length) : Autoarr2() {
template
Autoarr2::~Autoarr2() {
for (uint16 i=0;i::set(uint32 index, T value) {
template
void Autoarr2::add(T value) {
if(!values){
- //values=(T**)malloc(sizeof(T*));
values=new T*[1];
goto create_block;
}
@@ -83,9 +85,9 @@ create_block:
T** new_values=new T*[blocks_count+1];
for(uint32 i=0;i
-uint32 Autoarr2::search(T& value, cmp_func_t cmpf, uint32 fromIndex, uint32 toIndex){
+template
+uint32 Autoarr2::search(T& value, cmp_func_lambda cmpf, uint32 fromIndex, uint32 toIndex){
uint32 index=fromIndex;
for(; index::search(T& value, cmp_func_t cmpf, uint32 fromIndex, uint32 t
}
template
-uint32 Autoarr2::search(T& value, cmp_func_t cmpf, uint32 fromIndex){
+template
+uint32 Autoarr2::search(T& value, cmp_func_lambda cmpf, uint32 fromIndex){
return search(value, cmpf, fromIndex, length);
}
template
-uint32 Autoarr2::search(T& value, cmp_func_t cmpf){
+template
+uint32 Autoarr2::search(T& value, cmp_func_lambda cmpf){
return search(value, cmpf, 0, length);
}
+
+template
+void Autoarr2::remove(uint32 index){
+ throw_id(ERR_NOTIMPLEMENTED);
+}
\ No newline at end of file
diff --git a/src/Hashtable2/Hashtable2.hpp b/src/Hashtable2/Hashtable2.hpp
index eaa2c0b..67bb2e4 100644
--- a/src/Hashtable2/Hashtable2.hpp
+++ b/src/Hashtable2/Hashtable2.hpp
@@ -4,11 +4,10 @@
#include "../Autoarr2/Autoarr2.hpp"
// amount of rows
-typedef uint16 HT_HEIGHT_T;
+typedef uint32 HT_HEIGHT_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};
#define _HT_HEIN_MIN 0
@@ -20,162 +19,187 @@ static const HT_HEIGHT_T HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
template
class Hashtable2{
- using cmp_func_t=bool (*)(TKey, TKey);
-
+// internal types
+ struct KeyValue{
+ TKey key;
+ TVal value;
#if STORE_HASHES
- Autoarr2** hashes;
-
+ HT_HASH_T hash;
#endif
- cmp_func_t keyComparFunc;
- Autoarr2** keys;
- Autoarr2** values;
+ };
+ using HashKeyFunc_t=HT_HASH_T (*)(TKey);
+ using KeyCmpFunc_t=bool (*)(TKey, TKey);
+
+// fields
+ Autoarr2** rows;
+
+ HashKeyFunc_t hashKeyFunc;
+#if !STORE_HASHES
+ KeyCmpFunc_t keyComparFunc;
+#endif
+public:
+ HT_HEIGHT_T height;
+private:
uint8 hein;
- HT_HEIGHT_T _height;
- void expand();
- bool uint32_compare(uint32& a, uint32& b) { return a==b; }
+
+// constructors
#if STORE_HASHES
public:
#endif
- Hashtable2();
+ Hashtable2(HashKeyFunc_t _hashKeyFunc);
#if !STORE_HASHES
public:
- explicit Hashtable2(cmp_func_t _keyComparFunc);
+ explicit Hashtable2(HashKeyFunc_t _hashKeyFunc, KeyCmpFunc_t _keyComparFunc);
#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();
- inline HT_HEIGHT_T height(){ return _height; }
TVal* getptr(TKey key);
TVal get(TKey key);
- bool addOrSet(TKey key, TVal);
- bool remove(TKey);
+ bool tryGet(TKey key, TVal* output);
+ void add(TKey key, TVal value);
+ void addOrSet(TKey key, TVal value);
+ void remove(TKey key);
};
template
-Hashtable2::Hashtable2(){
+Hashtable2::Hashtable2(HashKeyFunc_t _hashKeyFunc){
+ hashKeyFunc=_hashKeyFunc;
hein=_HT_HEIN_MIN;
- _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);
- }
+ height=HT_HEIGHTS[hein];
+ rows=new Autoarr2*[height];
+ for(HT_HEIGHT_T i=0; i(_HT_ARR_BL);
}
#if !STORE_HASHES
template
-Hashtable2::Hashtable2(cmp_func_t _keyComparFunc) : Hashtable2() {
+Hashtable2::Hashtable2(HashKeyFunc_t _hashKeyFunc, KeyCmpFunc_t _keyComparFunc) : Hashtable2(_hashKeyFunc) {
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::free_rows(){
+ for(uint32 i=0; i< height; i++)
+ delete rows[i];
+ delete[] rows;
}
-
template
-void Hashtable2::expand(){
- if(hein>=_HT_HEIN_MAX)
- throw_id(ERR_MAXLENGTH);
- uint32 newHeight=HT_HEIGHTS[++hein];
- Autoarr2** newKeys=new Autoarr2*[newHeight];
- Autoarr2** newValues=new Autoarr2*[newHeight];
-#if STORE_HASHES
- Autoarr2** newHashes=new Autoarr2*[newHeight];
-#endif
-
- for(HT_HEIGHT_T i=0; i(_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<_height; rowN++){
- Autoarr2* oldKeysRow=keys[rowN];
- Autoarr2* oldValuesRow=values[rowN];
-#if STORE_HASHES
- Autoarr2* 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
-}
+Hashtable2::~Hashtable2() { free_rows(); }
template
-TVal* Hashtable2::getptr(TKey key){
- HT_HASH_T keyHash=HT_HASH(key);
- HT_HEIGHT_T rowN=keyHash%_height;
+TVal* Hashtable2::getptr(TKey key, HT_HASH_T& keyHash, HT_HEIGHT_T& rowN){
+ keyHash=hashKeyFunc(key);
+ rowN=keyHash%height;
+ KeyValue kv;
#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
- 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
if(index==Autoarr2_NO_REZULT)
return NULL;
- return values[rowN]->getptr(index);
+ return &(rows[rowN]->getptr(index))->value;
}
+template
+TVal* Hashtable2::getptr(TKey key){
+ HT_HASH_T keyHash;
+ HT_HEIGHT_T rowN;
+ return getptr(key, keyHash, rowN);
+}
template
TVal Hashtable2::get(TKey key){
-
+ TVal* ptr=getptr(key);
+ if(!ptr)
+ throw_id(ERR_KEYNOTFOUND);
+ return *ptr;
+}
+
+template
+bool Hashtable2::tryGet(TKey key, TVal* output){
+ TVal* ptr=getptr(key);
+ if(!ptr)
+ return false;
+ *output=*ptr;
+ return true;
+}
+
+template
+void Hashtable2::expand(){ printf("expand\n"); fflush(stdout);
+ if(hein>=_HT_HEIN_MAX)
+ throw_id(ERR_MAXLENGTH);
+
+ uint32 newHeight=HT_HEIGHTS[++hein];
+ Autoarr2** newRows=new Autoarr2*[newHeight];
+ for(HT_HEIGHT_T i=0; i(_HT_ARR_BL);
+
+ for(HT_HEIGHT_T oldRowN=0; oldRowNlength; 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
+void Hashtable2::add(TKey& key, TVal& value, HT_HASH_T keyHash, HT_HEIGHT_T rowN){ printf("add\n"); fflush(stdout);
+ Autoarr2* 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
+void Hashtable2::add(TKey key, TVal value){
+ HT_HASH_T keyHash=hashKeyFunc(key);
+ HT_HEIGHT_T rowN=keyHash%height;
+ add(key, value, keyHash, rowN);
+}
+
+template
+void Hashtable2::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
-bool Hashtable2::addOrSet(TKey key, TVal){
- //expand
-}
-
-
-template
-bool Hashtable2::remove(TKey){
-
+void Hashtable2::remove(TKey key){
+ throw_id(ERR_NOTIMPLEMENTED);
}
diff --git a/src/base/errors.c b/src/base/errors.c
index 1df7552..e3f61a2 100644
--- a/src/base/errors.c
+++ b/src/base/errors.c
@@ -11,7 +11,7 @@ char* errname(ErrorId err){
case ERR_NOTIMPLEMENTED: return "ERR_NOTIMPLEMENTED";
case ERR_NULLPTR: return "ERR_NULLPTR";
case ERR_ENDOFSTR: return "ERR_ENDOFSTR";
- case ERR_DESYNC: return "ERR_DESYNC";
+ case ERR_KEYNOTFOUND: return "ERR_KEYNOTFOUND";
default: return "UNKNOWN_ERROR";
}
}
diff --git a/src/base/errors.h b/src/base/errors.h
index c4c59b5..eb347dc 100644
--- a/src/base/errors.h
+++ b/src/base/errors.h
@@ -11,7 +11,7 @@ typedef enum ErrorId {
SUCCESS, // not an error
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
- ERR_DESYNC
+ ERR_KEYNOTFOUND
} ErrorId;
char* errname(ErrorId err);
@@ -51,10 +51,10 @@ char* __unknownErr( );
#if __cplusplus
#define throw_id(E) __EXIT(((char*)__genErrMsg(errname(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
-#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){\
freeMem;\
diff --git a/tests/main.cpp b/tests/main.cpp
index ab78183..3f7da09 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -4,12 +4,12 @@ void test_all(){
// test_string();
// test_safethrow();
// test_searchtree();
- test_autoarr();
- test_autoarr2();
+ // test_autoarr();
+ // test_autoarr2();
// test_hash_functions();
- test_hashtable();
+ // test_hashtable();
+ // test_dtsod();
test_hashtable2();
- //test_dtsod();
printf("\e[96m--------------------------------------\e[0m\n");
}
diff --git a/tests/test_hashtable2.cpp b/tests/test_hashtable2.cpp
index b06d8ec..558d6ed 100644
--- a/tests/test_hashtable2.cpp
+++ b/tests/test_hashtable2.cpp
@@ -1,58 +1,65 @@
#include "tests.h"
#include "../src/Hashtable2/Hashtable2.hpp"
+#include
-#define TKey char*
+#define TKey std::shared_ptr
#define TVal uint64
#define HT_TYPE Hashtable2
-#define HT_TYPE_NAME "Hashtable2"
+#define HT_TYPE_NAME "Hashtable2, uint64>"
void print_hashtable(HT_TYPE* ht){
printf("\e[94m" HT_TYPE_NAME ": "
IFWIN("%llu", "%lu")
"\n height: %u\n",
sizeof(HT_TYPE),
- ht->height());
+ ht->height);
}
-char* genkey(uint32 i){
- char* key=new char[16];
+std::shared_ptr genkey(uint32 i){
+ char* key=new char[24];
IFMSC(
- sprintf_s(key,16,"key_%u",i),
+ sprintf_s(key,24,"key_%u",i),
sprintf(key,"key_%u",i)
);
- return key;
+ dbg(i);
+ return std::shared_ptr(key, [](char* s){ delete[] s;});
}
void fill(HT_TYPE* ht){
- //for(uint32 i=0;i<100000;i++)
- // ht->add(genkey(i),Uni(UInt64,i));
+ for(uint32 i=0;i<251;i++)
+ ht->add(genkey(i), 555666);
+ print_hashtable(ht);
}
TVal gett(HT_TYPE* ht){
TVal u;
- for(uint32 i=0;i<100000;i++){
+ for(uint32 i=0;i<1000;i++){
TKey key=genkey(i);
- //u=ht->get(key);
- delete[] key;
+ u=ht->get(key);
}
return u;
}
void test_hashtable2(){
- optime("test_hashtable2",1,({
+ //optime("test_hashtable2",1,({
printf("\e[96m-----------[test_hashtable2]-----------\n");
#if STORE_HASHES
- HT_TYPE* ht=new HT_TYPE();
+ HT_TYPE* ht=new HT_TYPE(
+ [](TKey k) { return hashs(hash_sdbm32,k.get()); });
#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
- printf("\e[92m" HT_TYPE_NAME " created\n");
+ printf("\e[92mhashtable created\n");
print_hashtable(ht);
optime("fill",1,fill(ht));
- optime("get",1,gett(ht));
- print_hashtable(ht);
+ // TVal r;
+ // optime("get",1,r=gett(ht));
+ // dbg((uint32)r);
+ // print_hashtable(ht);
delete ht;
- printf("\e[92m" HT_TYPE_NAME " deleted\n");
- }));
+ printf("\e[92mhashtable deleted\n");
+ //}));
}