diff --git a/3rd/dmath/dmath b/3rd/dmath/dmath index 164cd919..2d9e0470 160000 --- a/3rd/dmath/dmath +++ b/3rd/dmath/dmath @@ -1 +1 @@ -Subproject commit 164cd91963535e0ddb0bbada10d9597645459ec3 +Subproject commit 2d9e04701ddac77eb33eb7f9dcb24cab5bb10412 diff --git a/include/pocketpy/xmacros/fixedhash.h b/include/pocketpy/xmacros/fixedhash.h new file mode 100644 index 00000000..bcd0542b --- /dev/null +++ b/include/pocketpy/xmacros/fixedhash.h @@ -0,0 +1,107 @@ +#include "pocketpy/common/chunkedvector.h" +#include "pocketpy/config.h" +#include + +#if !defined(FIXEDHASH_T__HEADER) && !defined(FIXEDHASH_T__SOURCE) + +#define FIXEDHASH_T__HEADER +#define FIXEDHASH_T__SOURCE +/* Input */ +#define K int +#define V float +#define NAME c11_fixedhash_d2f +#endif + +/* Optional Input */ +#ifndef hash +#define hash(a) ((uint64_t)(a)) +#endif + +#ifndef equal +#define equal(a, b) ((a) == (b)) +#endif + +/* Temporary macros */ +#define CONCAT(A, B) CONCAT_(A, B) +#define CONCAT_(A, B) A##B + +#define KV CONCAT(NAME, _KV) +#define METHOD(name) CONCAT(NAME, CONCAT(__, name)) + +#ifdef FIXEDHASH_T__HEADER +/* Declaration */ +typedef struct { + uint64_t hash; + K key; + V val; +} KV; + +typedef struct { + int length; + uint16_t indices[0x10000]; + c11_chunkedvector /*T=FixedHashEntry*/ entries; +} NAME; + +void METHOD(ctor)(NAME* self); +void METHOD(dtor)(NAME* self); +NAME* METHOD(new)(); +void METHOD(delete)(NAME* self); +void METHOD(set)(NAME* self, K key, V* value); +V* METHOD(try_get)(NAME* self, K key); + +#endif + +#ifdef FIXEDHASH_T__SOURCE +/* Implementation */ + +void METHOD(ctor)(NAME* self) { + self->length = 0; + memset(self->indices, 0xFF, sizeof(self->indices)); + c11_chunkedvector__ctor(&self->entries, sizeof(KV), 0); +} + +void METHOD(dtor)(NAME* self) { c11_chunkedvector__dtor(&self->entries); } + +NAME* METHOD(new)() { + NAME* self = PK_MALLOC(sizeof(NAME)); + METHOD(ctor)(self); + return self; +} + +void METHOD(delete)(NAME* self) { + METHOD(dtor)(self); + PK_FREE(self); +} + +void METHOD(set)(NAME* self, K key, V* value) { + uint64_t hash_value = hash(key); + int index = (uint16_t)(hash_value & 0xFFFF); + while(self->indices[index] != 0xFFFF) { + KV* entry = c11_chunkedvector__at(&self->entries, self->indices[index]); + if(equal(entry->key, key)) { + entry->val = *value; + return; + } + index = ((5 * index) + 1) & 0xFFFF; + } + if(self->length >= 65000) abort(); + KV* kv = c11_chunkedvector__emplace(&self->entries); + kv->hash = hash_value; + kv->key = key; + kv->val = *value; + self->indices[index] = self->entries.length - 1; + self->length++; +} + +V* METHOD(try_get)(NAME* self, K key) { + uint64_t hash_value = hash(key); + int index = (uint16_t)(hash_value & 0xFFFF); + while(self->indices[index] != 0xFFFF) { + KV* entry = c11_chunkedvector__at(&self->entries, self->indices[index]); + if(equal(entry->key, key)) return &entry->val; + index = ((5 * index) + 1) & 0xFFFF; + } + return NULL; +} + +#endif \ No newline at end of file