Added a cast for malloc to enable clean
compilation as C++
*/
+#include <stdlib.h>
+#include <string.h>
+
#include "jsw_hlib.h"
-#include <stdlib.h>
typedef struct jsw_node {
void *key; /* Key used for searching */
itemrel_f itemrel; /* User defined item delete function */
};
+static unsigned int default_hash(const void *key) {
+ const unsigned char *p = key;
+ unsigned h = 0;
+ int i;
+ int len = strlen((char *)p);
+
+ for (i = 0; i < len; i++) {
+ h += p[i];
+ h += (h << 10);
+ h ^= (h >> 6);
+ }
+
+ h += (h << 3);
+ h ^= (h >> 11);
+ h += (h << 15);
+
+ return h;
+}
+
static jsw_node_t *new_node ( void *key, void *item, jsw_node_t *next )
{
jsw_node_t *node = malloc ( sizeof *node );
htab->capacity = size;
htab->curri = 0;
htab->currl = NULL;
- htab->hash = hash;
+ htab->hash = hash ? hash : default_hash;
htab->cmp = cmp;
htab->keydup = keydup;
htab->itemdup = itemdup;
return NULL;
}
+static int insert_item(jsw_head_t **table, jsw_node_t *item, unsigned int chain) {
+ /* Create a chain if the bucket is empty */
+ if ( table[chain] == NULL ) {
+ table[chain] = new_chain();
+ }
+
+ if ( table[chain] == NULL ) {
+ return 0;
+ }
+
+ /* Insert at the front of the chain */
+ item->next = table[chain]->first;
+ table[chain]->first = item;
+
+ ++table[chain]->size;
+
+ return 1;
+}
+
/*
Insert an item with the selected key
*/
int jsw_hresize ( jsw_hash_t *htab, size_t new_size )
{
- jsw_hash_t *new_htab;
jsw_node_t *it;
+ jsw_head_t **newtable;
size_t i;
+ unsigned int bucket;
- /* Build a new hash table, then assign it to the old one */
- new_htab = jsw_hnew ( new_size, htab->hash, htab->cmp,
- htab->keydup, htab->itemdup, htab->keyrel, htab->itemrel );
+ if (new_size == htab->capacity) {
+ return 1;
+ }
- if ( new_htab == NULL )
- return 0;
+ newtable = malloc(new_size * sizeof *htab->table);
+
+ if (!newtable) {
+ return 0;
+ }
+
+ for(i=0; i < new_size; i++) {
+ newtable[i] = 0;
+ }
for ( i = 0; i < htab->capacity; i++ ) {
- if ( htab->table[i] == NULL )
- continue;
+ if ( htab->table[i] == NULL ) continue;
- for ( it = htab->table[i]->first; it != NULL; it = it->next )
- jsw_hinsert ( new_htab, it->key, it->item );
+ for ( it = htab->table[i]->first; it != NULL; it = it->next ) {
+ bucket = htab->hash(it->key) % new_size;
+ insert_item(newtable, it, bucket);
+ }
}
- /* A hash table holds copies, so release the old table */
- jsw_hdelete ( htab );
- htab = new_htab;
+ htab->capacity = new_size;
+ htab->table = newtable;
return 1;
}