Quellcode durchsuchen

add `fixedhash`

blueloveTH vor 8 Monaten
Ursprung
Commit
778d970323
2 geänderte Dateien mit 108 neuen und 1 gelöschten Zeilen
  1. 1 1
      3rd/dmath/dmath
  2. 107 0
      include/pocketpy/xmacros/fixedhash.h

+ 1 - 1
3rd/dmath/dmath

@@ -1 +1 @@
-Subproject commit 164cd91963535e0ddb0bbada10d9597645459ec3
+Subproject commit 2d9e04701ddac77eb33eb7f9dcb24cab5bb10412

+ 107 - 0
include/pocketpy/xmacros/fixedhash.h

@@ -0,0 +1,107 @@
+#include "pocketpy/common/chunkedvector.h"
+#include "pocketpy/config.h"
+#include <stdint.h>
+
+#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