98#include "utilities/qhash.h"
99#include "containers/qhashtbl.h"
101#define DEFAULT_INDEX_RANGE (1000)
132 qhashtbl_t *tbl = (qhashtbl_t *) calloc(1,
sizeof(qhashtbl_t));
137 tbl->slots = (qhashtbl_obj_t **) calloc(range,
sizeof(qhashtbl_obj_t *));
138 if (tbl->slots == NULL)
142 if (options & QHASHTBL_THREADSAFE) {
143 Q_MUTEX_NEW(tbl->qmutex,
true);
144 if (tbl->qmutex == NULL)
179 assert(tbl->qmutex == NULL);
200 if (name == NULL || data == NULL) {
207 int idx = hash % tbl->range;
213 for (obj = tbl->slots[idx]; obj != NULL; obj = obj->next) {
214 if (obj->hash == hash && !strcmp(obj->name, name)) {
220 char *dupname = strdup(name);
221 void *dupdata = malloc(size);
222 if (dupname == NULL || dupdata == NULL) {
229 memcpy(dupdata, data, size);
234 obj = (qhashtbl_obj_t *) calloc(1,
sizeof(qhashtbl_obj_t));
243 if (tbl->slots[idx] != NULL) {
245 obj->next = tbl->slots[idx];
247 tbl->slots[idx] = obj;
280 return qhashtbl_put(tbl, name, str, (str != NULL) ? (strlen(str) + 1) : 0);
297 DYNAMIC_VSPRINTF(str, format);
325 snprintf(str,
sizeof(str),
"%"PRId64, num);
363void *
qhashtbl_get(qhashtbl_t *tbl,
const char *name,
size_t *size,
bool newmem) {
370 int idx = hash % tbl->range;
376 for (obj = tbl->slots[idx]; obj != NULL; obj = obj->next) {
377 if (obj->hash == hash && !strcmp(obj->name, name)) {
384 if (newmem ==
false) {
387 data = malloc(obj->size);
392 memcpy(data, obj->data, obj->size);
394 if (size != NULL && data != NULL)
470 int idx = hash % tbl->range;
474 qhashtbl_obj_t *prev = NULL;
476 for (obj = tbl->slots[idx]; obj != NULL; obj = obj->next) {
477 if (obj->hash == hash && !strcmp(obj->name, name)) {
480 tbl->slots[idx] = obj->next;
482 prev->next = obj->next;
553 qhashtbl_obj_t *cursor = NULL;
555 if (obj->name != NULL) {
556 idx = (obj->hash % tbl->range) + 1;
560 if (cursor != NULL) {
565 for (; idx < tbl->range; idx++) {
566 if (tbl->slots[idx] != NULL) {
567 cursor = tbl->slots[idx];
574 if (cursor != NULL) {
575 if (newmem ==
true) {
576 obj->name = strdup(cursor->name);
577 obj->data = malloc(cursor->size);
578 if (obj->name == NULL || obj->data == NULL) {
579 DEBUG(
"getnext(): Unable to allocate memory.");
586 memcpy(obj->data, cursor->data, cursor->size);
587 obj->size = cursor->size;
589 obj->name = cursor->name;
590 obj->data = cursor->data;
592 obj->hash = cursor->hash;
593 obj->size = cursor->size;
594 obj->next = cursor->next;
625 for (idx = 0; idx < tbl->range && tbl->num > 0; idx++) {
626 if (tbl->slots[idx] == NULL)
628 qhashtbl_obj_t *obj = tbl->slots[idx];
629 tbl->slots[idx] = NULL;
630 while (obj != NULL) {
631 qhashtbl_obj_t *next = obj->next;
661 memset((
void *) &obj, 0,
sizeof(obj));
663 while (tbl->getnext(tbl, &obj,
false) ==
true) {
664 fprintf(out,
"%s=", obj.name);
665 _q_textout(out, obj.data, obj.size, MAX_HUMANOUT);
666 fprintf(out,
" (%zu, %08x)\n", obj.size, obj.hash);
687 Q_MUTEX_ENTER(tbl->qmutex);
700 Q_MUTEX_LEAVE(tbl->qmutex);
713 Q_MUTEX_DESTROY(tbl->qmutex);
uint32_t qhashmurmur3_32(const void *data, size_t nbytes)
Get 32-bit Murmur3 hash.
bool qhashtbl_remove(qhashtbl_t *tbl, const char *name)
qhashtbl->remove(): Remove an object from this table.
bool qhashtbl_debug(qhashtbl_t *tbl, FILE *out)
qhashtbl->debug(): Print hash table for debugging purpose
void qhashtbl_clear(qhashtbl_t *tbl)
qhashtbl->clear(): Clears this hashtable so that it contains no keys.
int64_t qhashtbl_getint(qhashtbl_t *tbl, const char *name)
qhashtbl->getint(): Finds an object with given name and returns as integer type.
void qhashtbl_unlock(qhashtbl_t *tbl)
qhashtbl->unlock(): Leave critical section.
#define DEFAULT_INDEX_RANGE
void qhashtbl_free(qhashtbl_t *tbl)
qhashtbl->free(): De-allocate hash table
bool qhashtbl_getnext(qhashtbl_t *tbl, qhashtbl_obj_t *obj, const bool newmem)
qhashtbl->getnext(): Get next element.
size_t qhashtbl_size(qhashtbl_t *tbl)
qhashtbl->size(): Returns the number of keys in this hashtable.
qhashtbl_t * qhashtbl(size_t range, int options)
Initialize hash table.
void qhashtbl_lock(qhashtbl_t *tbl)
qhashtbl->lock(): Enter critical section.
bool qhashtbl_putstr(qhashtbl_t *tbl, const char *name, const char *str)
qhashtbl->putstr(): Put a string into this table.
bool qhashtbl_put(qhashtbl_t *tbl, const char *name, const void *data, size_t size)
qhashtbl->put(): Put an object into this table.
bool qhashtbl_putstrf(qhashtbl_t *tbl, const char *name, const char *format,...)
qhashtbl->putstrf(): Put a formatted string into this table.
char * qhashtbl_getstr(qhashtbl_t *tbl, const char *name, const bool newmem)
qhashtbl->getstr(): Finds an object and returns as string type.
void * qhashtbl_get(qhashtbl_t *tbl, const char *name, size_t *size, bool newmem)
qhashtbl->get(): Get an object from this table.
bool qhashtbl_putint(qhashtbl_t *tbl, const char *name, const int64_t num)
qhashtbl->putint(): Put a integer into this table as string type.