// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. // Copyright (c) 2018 Evol developers #include "common/hercules.h" #include #include #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; }