97 #include "qinternal.h"
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)
180 assert(tbl->qmutex == NULL);
201 if (name == NULL || data == NULL) {
208 int idx = hash % tbl->range;
214 for (obj = tbl->slots[idx]; obj != NULL; obj = obj->next) {
215 if (obj->hash == hash && !strcmp(obj->name, name)) {
221 char *dupname = strdup(name);
222 void *dupdata = malloc(size);
223 if (dupname == NULL || dupdata == NULL) {
230 memcpy(dupdata, data, size);
235 obj = (qhashtbl_obj_t *) calloc(1,
sizeof(qhashtbl_obj_t));
244 if (tbl->slots[idx] != NULL) {
246 obj->next = tbl->slots[idx];
248 tbl->slots[idx] = obj;
281 return qhashtbl_put(tbl, name, str, (str != NULL) ? (strlen(str) + 1) : 0);
298 DYNAMIC_VSPRINTF(str, format);
326 snprintf(str,
sizeof(str),
"%"PRId64, num);
364 void *
qhashtbl_get(qhashtbl_t *tbl,
const char *name,
size_t *size,
bool newmem) {
371 int idx = hash % tbl->range;
377 for (obj = tbl->slots[idx]; obj != NULL; obj = obj->next) {
378 if (obj->hash == hash && !strcmp(obj->name, name)) {
385 if (newmem ==
false) {
388 data = malloc(obj->size);
393 memcpy(data, obj->data, obj->size);
395 if (size != NULL && data != NULL)
471 int idx = hash % tbl->range;
475 qhashtbl_obj_t *prev = NULL;
477 for (obj = tbl->slots[idx]; obj != NULL; obj = obj->next) {
478 if (obj->hash == hash && !strcmp(obj->name, name)) {
481 tbl->slots[idx] = obj->next;
483 prev->next = obj->next;
554 qhashtbl_obj_t *cursor = NULL;
556 if (obj->name != NULL) {
557 idx = (obj->hash % tbl->range) + 1;
561 if (cursor != NULL) {
566 for (; idx < tbl->range; idx++) {
567 if (tbl->slots[idx] != NULL) {
568 cursor = tbl->slots[idx];
575 if (cursor != NULL) {
576 if (newmem ==
true) {
577 obj->name = strdup(cursor->name);
578 obj->data = malloc(cursor->size);
579 if (obj->name == NULL || obj->data == NULL) {
580 DEBUG(
"getnext(): Unable to allocate memory.");
587 memcpy(obj->data, cursor->data, cursor->size);
588 obj->size = cursor->size;
590 obj->name = cursor->name;
591 obj->data = cursor->data;
593 obj->hash = cursor->hash;
594 obj->size = cursor->size;
595 obj->next = cursor->next;
626 for (idx = 0; idx < tbl->range && tbl->num > 0; idx++) {
627 if (tbl->slots[idx] == NULL)
629 qhashtbl_obj_t *obj = tbl->slots[idx];
630 tbl->slots[idx] = NULL;
631 while (obj != NULL) {
632 qhashtbl_obj_t *next = obj->next;
662 memset((
void *) &obj, 0,
sizeof(obj));
664 while (tbl->getnext(tbl, &obj,
false) ==
true) {
665 fprintf(out,
"%s=", obj.name);
666 _q_textout(out, obj.data, obj.size, MAX_HUMANOUT);
667 fprintf(out,
" (%zu, hash=%u)\n", obj.size, obj.hash);
688 Q_MUTEX_ENTER(tbl->qmutex);
701 Q_MUTEX_LEAVE(tbl->qmutex);
714 Q_MUTEX_DESTROY(tbl->qmutex);
bool qhashtbl_remove(qhashtbl_t *tbl, const char *name)
qhashtbl->remove(): Remove an object from this table.
size_t qhashtbl_size(qhashtbl_t *tbl)
qhashtbl->size(): Returns the number of keys in this hashtable.
void qhashtbl_free(qhashtbl_t *tbl)
qhashtbl->free(): De-allocate hash 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.
void qhashtbl_clear(qhashtbl_t *tbl)
qhashtbl->clear(): Clears this hashtable so that it contains no keys.
bool qhashtbl_putstr(qhashtbl_t *tbl, const char *name, const char *str)
qhashtbl->putstr(): Put a string into this table.
void qhashtbl_lock(qhashtbl_t *tbl)
qhashtbl->lock(): Enter critical section.
int64_t qhashtbl_getint(qhashtbl_t *tbl, const char *name)
qhashtbl->getint(): Finds an object with given name and returns as integer type.
bool qhashtbl_put(qhashtbl_t *tbl, const char *name, const void *data, size_t size)
qhashtbl->put(): Put an object 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.
#define DEFAULT_INDEX_RANGE
uint32_t qhashmurmur3_32(const void *data, size_t nbytes)
Get 32-bit Murmur3 hash.
qhashtbl_t * qhashtbl(size_t range, int options)
Initialize hash table.
void qhashtbl_unlock(qhashtbl_t *tbl)
qhashtbl->unlock(): Leave critical section.
bool qhashtbl_getnext(qhashtbl_t *tbl, qhashtbl_obj_t *obj, const bool newmem)
qhashtbl->getnext(): Get next element.
bool qhashtbl_putstrf(qhashtbl_t *tbl, const char *name, const char *format,...)
qhashtbl->putstrf(): Put a formatted string into this table.
void * qhashtbl_get(qhashtbl_t *tbl, const char *name, size_t *size, bool newmem)
qhashtbl->get(): Get an object from this table.
bool qhashtbl_debug(qhashtbl_t *tbl, FILE *out)
qhashtbl->debug(): Print hash table for debugging purpose