The qDecoder Project

qHasharr.c File Reference

Array based Hash-table Data Structure API. More...


Functions

size_t qHasharrSize (int max)
 Get how much memory is needed for N entries.
int qHasharr (Q_HASHARR *tbl, size_t memsize)
 Initialize array-hash table.
static bool _put (Q_HASHARR *tbl, const char *key, const void *value, int size)
 Q_HASHARR->put(): Put object into hash table.
static bool _putStr (Q_HASHARR *tbl, const char *key, const char *str)
 Q_HASHARR->putStr(): Put string into hash table.
static bool _putInt (Q_HASHARR *tbl, const char *key, int num)
 Q_HASHARR->putInt(): Put integer into hash table.
static void * _get (Q_HASHARR *tbl, const char *key, int *size)
 Q_HASHARR->get(): Get object from hash table.
static char * _getStr (Q_HASHARR *tbl, const char *key)
 Q_HASHARR->getStr(): Get string from hash table.
static int _getInt (Q_HASHARR *tbl, const char *key)
 Q_HASHARR->getInt(): Get integer from hash table.
static const char * _getNext (Q_HASHARR *tbl, int *idx)
 Q_HASHARR->getNext(): Get next key name.
static bool _remove (Q_HASHARR *tbl, const char *key)
 Q_HASHARR->remove(): Remove key from hash table.
static bool _truncate (Q_HASHARR *tbl)
 Q_HASHARR->truncate(): Truncate array-hash table.
static bool _print (Q_HASHARR *tbl, FILE *out)
 Q_HASHARR->print(): Print hash table for debugging purpose.
static int _getNum (Q_HASHARR *tbl)
 Q_HASHARR->getNum(): Get number of objects stored.
static int _getMax (Q_HASHARR *tbl)
 Q_HASHARR->getMax(): Get number of object slots.


Detailed Description

Array based Hash-table Data Structure API.

Note:
This Aarray-hash-table does not support thread-safe feature because this table is designed for statically assigned array like shared memory and most of this cases use fork() & semaphore based program model. In case of multiple access of this table, you should provide some kind of lock mechanism to prevent multiple modification of table at same time. qDecoder also have thread-safe Dynamic Hash-table, please refer qHashtbl().
In this array hash-table, we use some technics to effectively use memory. To verify key we use two way, if the key is smaller than (_Q_HASHARR_MAX_KEYSIZE - 1), we compare key itself. But if the key is bigger than (_Q_HASHARR_MAX_KEYSIZE - 1), we compare md5 of key and key length. If the key length and md5 of key are same we consider it's same key. So we don't need to store full key string. Actually it's not necessary to keep original key string, but we keep this because of two reasons. 1) if the length of the key is smaller than 16, it will be little bit quicker to compare key. 2) debugging reason.

Basically this hash-table based on array defines small size slot then it can links several slot for one data. This mechanism can save some wastes of memory. You can adjust default slot size to modify _Q_HASHARR_DEF_VALUESIZE.

   int maxkeys = 1000;

   // calculate how many memory do we need
   size_t memsize = qHasharrSize(maxkeys * 2); // generally allocate double size of max to decrease hash collision

   // allocate memory
   Q_HASHARR *hasharr = (Q_HASHARR *)malloc(memsize);

   // initialize hash-table
   if(qHasharr(hasharr, memsize) == 0) return -1;

   // put some sample data
   if(hasharr->put(hasharr, "sample1", "binary", 6) == false) return -1; // hash-table full
   if(hasharr->putStr(hasharr, "sample2", "string") == false) return -1; // hash-table full
   if(hasharr->putInt(hasharr, "sample3", 3) == false) return -1; // hash-table full

   // fetch data
   int size;
   char *sample_bin = hasharr->get(hasharr, "sample1", &size);
   char *sample_str = hasharr->getStr(hasharr, "sample2");
   int  sample_int  = hasharr->getInt(hasharr, "sample3");

Another simple way to initialize hash-table.

   // define data memory as much as you needed.
   char datamem[10 * 1024];

   // just set the Q_HASHARR points to data memory.
   Q_HASHARR *hasharr = (Q_HASHARR *)datamem;

   // initialize hash-table.
   if(qHasharr(hasharr, sizeof(datamem)) == 0) return -1;

   (...your codes here...)

   // no need to free unless you use malloc()

You can create hash table on shared memory like below.

   int maxkeys = 1000;
   int memsize = qHasharrSize(maxkeys * 2);

   // create shared memory
   int shmid = qShmInit(g_conf.szEgisdavdPidfile, 's', memsize, true);
   if(shmid < 0) return -1; // creation failed
   Q_HASHARR *tbl = (Q_HASHARR *)qShmGet(shmid);

   // initialize hash-table
   if(qHasharr(tbl, memsize) == 0) return -1;

   (...your codes here...)

   // destroy shared memory
   qShmFree(shmid);

Function Documentation

size_t qHasharrSize ( int  max  ) 

Get how much memory is needed for N entries.

Parameters:
max a number of maximum internal slots
Returns:
memory size needed
Note:
This is useful when you decide how much memory(shared-memory) required for N object entries. Be sure, a single object can be stored in several slots. So you need to consider additional slots if some data is bigger than _Q_HASHARR_DEF_VALUESIZE. By default, _Q_HASHARR_DEF_VALUESIZE is 32. This means if the size of object is bigger than 32 bytes it will use another slot.

int qHasharr ( Q_HASHARR tbl,
size_t  memsize 
)

Initialize array-hash table.

Parameters:
tbl a pointer of Q_HASHARR
memsize actual size of Q_HASHARR
Returns:
maximum number of available slots if successful, otherwise returns 0
   // allocate memory
   size_t memsize = qHasharrSize(100);
   Q_HASHARR *hasharr = (Q_HASHARR *)malloc(memsize);

   // initialize hash-table
   if(qHasharr(hasharr, memsize) == 0) return -1;

   int maxkeys = 1000;
   int memsize = qHasharrSize(maxkeys * 2);

   // create shared memory
   int shmid = qShmInit(g_conf.szEgisdavdPidfile, 's', memsize, true);
   if(shmid < 0) return -1; // creation failed
   Q_HASHARR *tbl = (Q_HASHARR *)qShmGet(shmid);

   // initialize hash-table
   if(qHasharr(tbl, memsize) == 0) return -1;

   (...your codes here...)

   // destroy shared memory
   qShmFree(shmid);

static bool _put ( Q_HASHARR tbl,
const char *  key,
const void *  value,
int  size 
) [static]

Q_HASHARR->put(): Put object into hash table.

Parameters:
tbl a pointer of Q_HASHARR
key key string
value value object data
size size of value
Returns:
true if successful, otherwise returns false

static bool _putStr ( Q_HASHARR tbl,
const char *  key,
const char *  str 
) [static]

Q_HASHARR->putStr(): Put string into hash table.

Parameters:
tbl a pointer of Q_HASHARR
key key string
value value string
Returns:
true if successful, otherwise returns false

static bool _putInt ( Q_HASHARR tbl,
const char *  key,
int  num 
) [static]

Q_HASHARR->putInt(): Put integer into hash table.

Parameters:
tbl a pointer of Q_HASHARR
key key string
value value integer
Returns:
true if successful, otherwise returns false

static void* _get ( Q_HASHARR tbl,
const char *  key,
int *  size 
) [static]

Q_HASHARR->get(): Get object from hash table.

Parameters:
tbl a pointer of Q_HASHARR
key key string
size if not NULL, oject size will be stored
Returns:
malloced object pointer if successful, otherwise(not found) returns NULL
Note:
returned object must be freed after done using.

static char* _getStr ( Q_HASHARR tbl,
const char *  key 
) [static]

Q_HASHARR->getStr(): Get string from hash table.

Parameters:
tbl a pointer of Q_HASHARR
key key string
Returns:
string pointer if successful, otherwise(not found) returns NULL
Note:
returned object must be freed after done using.

static int _getInt ( Q_HASHARR tbl,
const char *  key 
) [static]

Q_HASHARR->getInt(): Get integer from hash table.

Parameters:
tbl a pointer of Q_HASHARR
key key string
Returns:
value integer if successful, otherwise(not found) returns 0

static const char* _getNext ( Q_HASHARR tbl,
int *  idx 
) [static]

Q_HASHARR->getNext(): Get next key name.

Parameters:
tbl a pointer of Q_HASHARR
idx index pointer
Returns:
key name string if successful, otherwise(end of table) returns NULL
   int idx = 0;
   while(tbl->getNext(tbl, &idx) != NULL) {
     (... codes ...)
   }

Note:
Do not free returned key string.

static bool _remove ( Q_HASHARR tbl,
const char *  key 
) [static]

Q_HASHARR->remove(): Remove key from hash table.

Parameters:
tbl a pointer of Q_HASHARR
key key string
Returns:
true if successful, otherwise(not found) returns false

static bool _truncate ( Q_HASHARR tbl  )  [static]

Q_HASHARR->truncate(): Truncate array-hash table.

Parameters:
tbl a pointer of Q_HASHARR
Returns:
true if successful, otherwise returns false

static bool _print ( Q_HASHARR tbl,
FILE *  out 
) [static]

Q_HASHARR->print(): Print hash table for debugging purpose.

Parameters:
tbl a pointer of Q_HASHARR
out output stream
Returns:
true if successful, otherwise returns false

static int _getNum ( Q_HASHARR tbl  )  [static]

Q_HASHARR->getNum(): Get number of objects stored.

Parameters:
tbl a pointer of Q_HASHARR
Returns:
number of objects stored

static int _getMax ( Q_HASHARR tbl  )  [static]

Q_HASHARR->getMax(): Get number of object slots.

Parameters:
tbl a pointer of Q_HASHARR
Returns:
number of object slots
Note:
It is different from dynamic hash-table. In array-hash table, a value object can be stored in several slots if the size of the object is bigger than the size of slot. So used and max slot number is not equal to actual stored and maximum storable objects number.


Copyright (c) 2008 The qDecoder Project