|
| 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 a 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(): Put 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 the given name and returns it as a string.
|
| void * | qhasharr_get_by_obj (qhasharr_t *tbl, const void *name, size_t namesize, size_t *datasize) |
| | qhasharr->get_by_obj(): 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 the hash table for debugging purposes.
|
| void | qhasharr_free (qhasharr_t *tbl) |
| | qhasharr->free(): Free table reference object.
|
Static(array) hash-table implementation.
qhasharr implements a hash table that maps keys to values and stores them in fixed-size static memory such as shared memory and memory-mapped files. The creator qhasharr() initializes static memory and divides it into small slots. 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 its size exceeds the slot size. The key part of an element will be truncated if its length exceeds the limit, and an MD5 hash value will also be stored with the key. To look up a particular key, we first find an element that has the same hash value. If the key was not truncated, we simply compare the key values. If the key was truncated because its length exceeded the limit, we compare both the MD5 hash and the stored portion of the key to verify that the key is the same. Please be aware that, in theory, it is possible to pick the wrong element if a key exceeds the limit and has the same length and MD5 hash as the lookup key. In practice, however, this possibility is extremely low.
qhasharr intentionally does not provide thread-safe handling and lets users determine whether to provide a locking mechanism, depending on the use case. When race conditions are expected, you should provide shared-resource control using a mutex or semaphore to make sure data is 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| |
| +------------------+ +------------+ +------------+ +------------+ |
+--------------------------------------------------------------------------+
The diagram below shows how a large 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 a 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 to 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 the identifier of existing shared memory.
bool qshm_free(int shmid)
Free shared memory.
Definition in file qhasharr.c.