summaryrefslogtreecommitdiff
path: root/src/emap/judyarray.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emap/judyarray.c')
-rw-r--r--src/emap/judyarray.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/emap/judyarray.c b/src/emap/judyarray.c
new file mode 100644
index 0000000..bb6dda9
--- /dev/null
+++ b/src/emap/judyarray.c
@@ -0,0 +1,201 @@
+// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// Copyright (c) 2018 Evol developers
+
+#include "common/hercules.h"
+
+#include <Judy.h>
+#include <string.h>
+
+#include "common/db.h"
+#include "common/memmgr.h"
+#include "emap/judyarray.h"
+
+struct judy_interface judy_s;
+struct judy_interface *judy;
+
+int64 judy_new_array(void)
+{
+ int64 id = judy->last_id++;
+ void **PJSLArray;
+ JLI(PJSLArray, judy->arrays, id);
+ *PJSLArray = (void *)NULL;
+ return id;
+}
+
+bool judy_destroy_array(int64 id)
+{
+ int ret = 0;
+ judy->clear_array(id);
+ JLD(ret, judy->arrays, id);
+ return true;
+}
+
+bool judy_array_exists(int64 id)
+{
+ void **PJSLArray;
+ JLG(PJSLArray, judy->arrays, id);
+ return PJSLArray != NULL;
+}
+
+int64 judy_array_size(int64 id)
+{
+ void **PJSLArray;
+ JLG(PJSLArray, judy->arrays, id);
+
+ if (!PJSLArray)
+ return 0;
+
+ unsigned long sz = 0;
+ JLC(sz, *PJSLArray, 0, -1);
+ return sz;
+}
+
+bool judy_clear_array(int64 id)
+{
+ void **PJSLArray;
+ JLG(PJSLArray, judy->arrays, id);
+
+ if (PJSLArray)
+ {
+ uint8_t key[1];
+ void **PValue;
+ key[0] = '\0';
+ JSLF(PValue, *PJSLArray, key);
+
+ while (PValue && *PValue)
+ {
+ const struct DBData *result = (struct DBData *)(*PValue);
+ if (result->type == DB_DATA_PTR)
+ aFree(result->u.ptr);
+ aFree(*PValue);
+
+ int ret = 0;
+ JSLD(ret, *PJSLArray, key);
+ JSLF(PValue, *PJSLArray, key);
+ }
+ return true;
+ }
+ return false;
+}
+
+const struct DBData* judy_getvalue(int64 id, const char *key, const struct DBData *defval)
+{
+ void **PJSLArray;
+ void **PValue;
+ JLG(PJSLArray, judy->arrays, id);
+
+ if (!PJSLArray)
+ return defval; // array not found
+
+ JSLG(PValue, *PJSLArray, (unsigned char *)key);
+ if (PValue && *PValue)
+ return (struct DBData *)(*PValue);
+ return defval;
+}
+
+bool judy_setvalue(int64 id, const char *key, struct DBData *value)
+{
+ void **PJSLArray;
+ JLG(PJSLArray, judy->arrays, id);
+
+ if (!PJSLArray)
+ {
+ if (value->type == DB_DATA_PTR)
+ aFree(value->u.ptr);
+ aFree(value);
+ return false; // array not found
+ }
+
+ bool keep = true;
+
+ switch(value->type)
+ {
+ case DB_DATA_INT:
+ case DB_DATA_UINT:
+ keep = value->u.i;
+ break;
+ case DB_DATA_PTR:
+ keep = value->u.ptr && *(char*)value->u.ptr;
+ break;
+ }
+
+ if (keep)
+ {
+ void **PValue;
+ JSLI(PValue, *PJSLArray, (unsigned char *)key);
+
+ if (PValue && *PValue)
+ {
+ const struct DBData *prev = (struct DBData *)(*PValue);
+ if (prev->type == DB_DATA_PTR)
+ aFree(prev->u.ptr);
+ aFree(*PValue); // free any previously-set struct
+ }
+
+ *PValue = value;
+ return true;
+ }
+ else
+ {
+ // check if it previously existed, and free it
+ {
+ void **PValue;
+ JSLG(PValue, *PJSLArray, (unsigned char *)key);
+ if (PValue && *PValue)
+ {
+ const struct DBData *prev = (struct DBData *)(*PValue);
+ if (prev->type == DB_DATA_PTR)
+ aFree(prev->u.ptr);
+ aFree(*PValue);
+ }
+ }
+
+ int ret = 0;
+ JSLD(ret, *PJSLArray, (unsigned char *)key);
+ }
+
+ if (value->type == DB_DATA_PTR)
+ aFree(value->u.ptr);
+ aFree(value);
+ return true;
+}
+
+
+/**
+ * Initializer.
+ */
+void judy_init(void)
+{
+ judy->arrays = (void *)NULL; // this is a judyL array of judySL arrays
+}
+
+/**
+ * Finalizer.
+ */
+void judy_final(void)
+{
+ for (int64 id = 1; id <= judy->last_id; id++)
+ judy->destroy_array(id);
+
+ unsigned long sz = 0;
+ JLFA(sz, judy->arrays);
+ judy->arrays = NULL;
+}
+
+/**
+ * Interface defaults initializer.
+ */
+void judy_defaults(void)
+{
+ judy = &judy_s;
+
+ judy->last_id = 1;
+ judy->arrays = NULL;
+ judy->new_array = judy_new_array;
+ judy->clear_array = judy_clear_array;
+ judy->destroy_array = judy_destroy_array;
+ judy->array_exists = judy_array_exists;
+ judy->array_size = judy_array_size;
+ judy->getvalue = judy_getvalue;
+ judy->setvalue = judy_setvalue;
+}