|
size_t | qhasharr_calculate_memsize (int max) |
| Get how much memory is needed for N slots.
|
|
qhasharr_t * | qhasharr (void *memory, size_t memsize) |
| Initialize static hash table.
|
|
bool | qhasharr_put (qhasharr_t *tbl, const char *name, const void *data, size_t datasize) |
| qhasharr->put(): Put an object into this table.
|
|
bool | qhasharr_putstr (qhasharr_t *tbl, const char *name, const char *data) |
| qhasharr->putstr(): Put a string into this table
|
|
bool | qhasharr_putstrf (qhasharr_t *tbl, const char *name, const char *format,...) |
| qhasharr->putstrf(): Put a formatted string into this table.
|
|
bool | qhasharr_put_by_obj (qhasharr_t *tbl, const void *name, size_t namesize, const void *data, size_t datasize) |
| qhasharr->put_by_obj(): ut an object into this table by key object.
|
|
void * | qhasharr_get (qhasharr_t *tbl, const char *name, size_t *datasize) |
| qhasharr->get(): Get an object from this table
|
|
char * | qhasharr_getstr (qhasharr_t *tbl, const char *name) |
| qhasharr->getstr(): Finds an object with given name and returns as string type.
|
|
void * | qhasharr_get_by_obj (qhasharr_t *tbl, const void *name, size_t namesize, size_t *datasize) |
| qhasharr->get_by_object(): Get an object from this table by key object
|
|
bool | qhasharr_remove (qhasharr_t *tbl, const char *name) |
| qhasharr->remove(): Remove an object from this table.
|
|
bool | qhasharr_remove_by_obj (qhasharr_t *tbl, const char *name, size_t namesize) |
| qhasharr->remove_by_obj(): Remove an object from this table by key object
|
|
bool | qhasharr_remove_by_idx (qhasharr_t *tbl, int idx) |
| qhasharr->remove_by_idx(): Remove an object from this table by index number.
|
|
bool | qhasharr_getnext (qhasharr_t *tbl, qhasharr_obj_t *obj, int *idx) |
| qhasharr->getnext(): Get next element.
|
|
int | qhasharr_size (qhasharr_t *tbl, int *maxslots, int *usedslots) |
| qhasharr->size(): Returns the number of objects in this table.
|
|
void | qhasharr_clear (qhasharr_t *tbl) |
| qhasharr->clear(): Clears this table so that it contains no keys.
|
|
bool | qhasharr_debug (qhasharr_t *tbl, FILE *out) |
| qhasharr->debug(): Print hash table for debugging purpose
|
|
void | qhasharr_free (qhasharr_t *tbl) |
| qhasharr->free(): De-allocate table reference object.
|
|
Static(array) hash-table implementation.
qhasharr implements a hash-table which maps keys to values and stores into fixed size static memory like shared-memory and memory-mapped file. The creator qhasharr() initializes static memory to makes small slots in it. The default slot size factors are defined in Q_HASHARR_NAMESIZE and Q_HASHARR_DATASIZE. And they are applied at compile time.
The value part of an element will be stored across several slots if it's size exceeds the slot size. But the key part of an element will be truncated if the size exceeds and it's length and more complex MD5 hash value will be stored with the key. So to look up a particular key, first we find an element which has same hash value. If the key was not truncated, we just do key comparison. But if the key was truncated because it's length exceeds, we do both md5 and key comparison(only stored size) to verify that the key is same. So please be aware of that, theoretically there is a possibility we pick wrong element in case a key exceeds the limit, has same length and MD5 hash with lookup key. But this possibility is very low and almost zero in practice.
qhasharr hash-table does not provide thread-safe handling intentionally and let users determine whether to provide locking mechanism or not, depending on the use cases. When there's race conditions expected, you should provide a shared resource control using mutex or semaphore to make sure data gets updated by one instance at a time.
[Data Structure Diagram]
+--[Static Flat Memory Area]-----------------------------------------------+
| +-[Header]---------+ +-[Slot 0]---+ +-[Slot 1]---+ +-[Slot N]---+ |
| |Private table data| |KEY A|DATA A| |KEY B|DATA B| .... |KEY N|DATA N| |
| +------------------+ +------------+ +------------+ +------------+ |
+--------------------------------------------------------------------------+
Below diagram shows how a big value is stored.
+--[Static Flat Memory Area------------------------------------------------+
| +--------+ +-[Slot 0]---+ +-[Slot 1]---+ +-[Slot 2]---+ +-[Slot 3]-----+ |
| |TBL INFO| |KEY A|DATA A| |DATA A cont.| |KEY B|DATA B| |DATA A cont. | |
| +--------+ +------------+ +------------+ +------------+ +--------------+ |
| ^~~link~~^ ^~~~~~~~~~link~~~~~~~~~^ |
+--------------------------------------------------------------------------+
char memory[1000 * 10];
qhasharr_t *tbl =
qhasharr(memory,
sizeof(memory));
if(tbl == NULL) return;
tbl->putstr(tbl, "e1", "a");
tbl->putstr(tbl, "e2", "b");
tbl->putstr(tbl, "e3", "c");
tbl->debug(tbl, stdout);
char *e2 = tbl->getstr(tbl, "e2");
if(e2 != NULL) {
printf("getstr('e2') : %s\n", e2);
free(e2);
}
tbl->free(tbl);
qhasharr_t * qhasharr(void *memory, size_t memsize)
Initialize static hash table.
An example for using hash table over shared memory.
[CREATOR SIDE]
int maxslots = 1000;
int shmid =
qshm_init(
"/tmp/some_id_file",
'q', memsize,
true);
if(shmid < 0) return -1;
qhasharr_t *tbl =
qhasharr(memory, memsize);
if(hasharr == NULL) return -1;
(...your codes with your own locking mechanism...)
tbl->free(tbl);
[USER SIDE]
(...your codes with your own locking mechanism...)
tbl->free(tbl);
size_t qhasharr_calculate_memsize(int max)
Get how much memory is needed for N slots.
void * qshm_get(int shmid)
Get a pointer of shared memory.
int qshm_init(const char *keyfile, int keyid, size_t size, bool recreate)
Initialize shared-memory.
int qshm_getid(const char *keyfile, int keyid)
Get shared memory identifier by keyfile and keyid for existing shared memory.
bool qshm_free(int shmid)
De-allocate shared memory.
Definition in file qhasharr.c.