poldek: trurlib/libtrurl.sym, trurlib/n_hash_get.c, trurlib/n_hash...
mis
mis at pld-linux.org
Thu Jul 12 22:46:31 CEST 2007
Author: mis Date: Thu Jul 12 20:46:31 2007 GMT
Module: poldek Tag: HEAD
---- Log message:
- _ex() functions and cleanups
---- Files affected:
poldek/trurlib:
libtrurl.sym (1.3 -> 1.4) , n_hash_get.c (1.3 -> 1.4) , n_hash_int.h (1.9 -> 1.10) , n_hash_put.c (1.7 -> 1.8) , n_hash_stats.c (1.3 -> 1.4) , n_hash_new.c (1.12 -> 1.13)
poldek/trurlib/include/trurl:
nhash.h (1.13 -> 1.14)
---- Diffs:
================================================================
Index: poldek/trurlib/libtrurl.sym
diff -u poldek/trurlib/libtrurl.sym:1.3 poldek/trurlib/libtrurl.sym:1.4
--- poldek/trurlib/libtrurl.sym:1.3 Sun Aug 20 16:08:17 2006
+++ poldek/trurlib/libtrurl.sym Thu Jul 12 22:46:26 2007
@@ -73,10 +73,12 @@
n_hash_dump
n_hash_dup
n_hash_exists
+n_hash_exists_ex
n_hash_free
n_hash_get
-n_hash_get_bucket
+n_hash_get_ex
n_hash_insert
+n_hash_insert_ex
n_hash_keys
n_hash_keys_ext
n_hash_map
================================================================
Index: poldek/trurlib/n_hash_get.c
diff -u poldek/trurlib/n_hash_get.c:1.3 poldek/trurlib/n_hash_get.c:1.4
--- poldek/trurlib/n_hash_get.c:1.3 Wed Jun 23 20:11:26 2004
+++ poldek/trurlib/n_hash_get.c Thu Jul 12 22:46:26 2007
@@ -2,49 +2,15 @@
#include "n_hash_int.h"
-#if 0
-void *n_hash_get_ll(const tn_hash *ht, const char *key)
-{
- unsigned val = n_hash_dohash(ht, key, NULL);
- struct hash_bucket *ptr;
-
- if (ht->table[val] == NULL)
- return NULL;
-
- for (ptr = ht->table[val]; ptr != NULL; ptr = ptr->next) {
- if (strcmp(key, ptr->key) == 0)
- return ptr->data;
- }
-
- return NULL;
-}
-
-int n_hash_exists_ll(const tn_hash *ht, const char *key)
-{
- unsigned val = n_hash_dohash(ht, key, NULL);
- struct hash_bucket *ptr;
-
- if (NULL == ht->table[val])
- return 0;
-
- for (ptr = ht->table[val]; NULL != ptr; ptr = ptr->next) {
- if (0 == strcmp(key, ptr->key))
- return 1;
- }
-
- return 0;
-}
-#endif
-
static inline
struct hash_bucket *get_bucket_ll(struct hash_bucket **tbl,
- const char *key, unsigned val)
+ const char *key, unsigned khash)
{
struct hash_bucket *ptr;
- n_assert (tbl[val] != NULL);
+ n_assert (tbl[khash] != NULL);
- for (ptr = tbl[val]; ptr != NULL; ptr = ptr->next) {
+ for (ptr = tbl[khash]; ptr != NULL; ptr = ptr->next) {
if (strcmp(key, ptr->key) == 0)
return ptr;
}
@@ -53,41 +19,55 @@
struct hash_bucket *n_hash_get_bucket(const tn_hash *ht,
- const char *key, int klen, unsigned val)
+ const char *key, int klen, unsigned khash)
{
struct hash_bucket **tbl, *ptr = NULL;
tbl = ht->table;
- if (tbl[val] != NULL)
- ptr = get_bucket_ll(tbl, key, val);
+ if (tbl[khash] != NULL)
+ ptr = get_bucket_ll(tbl, key, khash);
if (ptr == NULL) {
- val += n_hash_nextslotv(key, klen);
- if (val < ht->size && tbl[val])
- ptr = get_bucket_ll(tbl, key, val);
+ khash += n_hash_nextslotv(key, klen);
+ if (khash < ht->size && tbl[khash])
+ ptr = get_bucket_ll(tbl, key, khash);
}
return ptr;
}
-void *n_hash_get(const tn_hash *ht, const char *key)
+void *n_hash_get_ex(const tn_hash *ht,
+ const char *key, int *klen, unsigned *khash)
{
struct hash_bucket *ptr;
- unsigned val;
- int klen;
- val = n_hash_dohash(ht, key, &klen);
- ptr = n_hash_get_bucket(ht, key, klen, val);
+ *khash = n_hash_dohash(ht, key, klen);
+ ptr = n_hash_get_bucket(ht, key, *klen, *khash);
return ptr ? ptr->data : NULL;
}
+
+void *n_hash_get(const tn_hash *ht, const char *key)
+{
+ unsigned khash;
+ int klen;
+
+ return n_hash_get_ex(ht, key, &klen, &khash);
+}
+
+int n_hash_exists_ex(const tn_hash *ht, const char *key, int *klen,
+ unsigned *khash)
+{
+ *khash = n_hash_dohash(ht, key, klen);
+ return n_hash_get_bucket(ht, key, *klen, *khash) != NULL;
+}
+
int n_hash_exists(const tn_hash *ht, const char *key)
{
- unsigned val;
int klen;
+ unsigned khash;
- val = n_hash_dohash(ht, key, &klen);
- return n_hash_get_bucket(ht, key, klen, val) != NULL;
+ return n_hash_exists_ex(ht, key, &klen, &khash);
}
================================================================
Index: poldek/trurlib/n_hash_int.h
diff -u poldek/trurlib/n_hash_int.h:1.9 poldek/trurlib/n_hash_int.h:1.10
--- poldek/trurlib/n_hash_int.h:1.9 Sat Aug 19 19:34:19 2006
+++ poldek/trurlib/n_hash_int.h Thu Jul 12 22:46:26 2007
@@ -62,3 +62,6 @@
struct hash_bucket *n_hash_get_bucket(const tn_hash *ht,
const char *key, int klen, unsigned val);
+
+int n_hash_exists_ex(const tn_hash *ht, const char *key, int *klen,
+ unsigned *khash);
================================================================
Index: poldek/trurlib/n_hash_put.c
diff -u poldek/trurlib/n_hash_put.c:1.7 poldek/trurlib/n_hash_put.c:1.8
--- poldek/trurlib/n_hash_put.c:1.7 Wed Jul 14 20:48:44 2004
+++ poldek/trurlib/n_hash_put.c Thu Jul 12 22:46:26 2007
@@ -153,19 +153,19 @@
#endif
static
-tn_hash *n_hash_put(tn_hash *ht, const char *key, const void *data, int replace)
+tn_hash *n_hash_put(tn_hash *ht, const char *key, int klen, unsigned khash,
+ const void *data, int replace)
{
struct hash_bucket *ptr;
- unsigned val;
- int klen;
if ((ht->flags & TN_HASH_REHASH) && ht->size - ht->items <= ht->size / 3)
n_hash_rehash(ht);
- val = n_hash_dohash(ht, key, &klen);
+ if (!khash)
+ khash = n_hash_dohash(ht, key, &klen);
if ((ht->flags & TN_HASH_NOREPLACE) == 0) {
- ptr = n_hash_get_bucket(ht, key, klen, val);
+ ptr = n_hash_get_bucket(ht, key, klen, khash);
if (ptr) {
if (!replace) {
trurl_die("n_hash_insert: key '%s' %s already in table\n",
@@ -180,13 +180,13 @@
}
}
- ptr = ht->table[val];
+ ptr = ht->table[khash];
if (ptr != NULL && ptr->next) {
- unsigned nextval = val + n_hash_nextslotv(key, klen);
+ unsigned nextval = khash + n_hash_nextslotv(key, klen);
if (nextval < ht->size) {
if ((ptr = ht->table[nextval]) == NULL) {
- DBGF("%d. nextmove(%d) %s[%d]\n", moves++, val, key, klen);
- val = nextval;
+ DBGF("%d. nextmove(%d) %s[%d]\n", moves++, khash, key, klen);
+ khash = nextval;
}
}
}
@@ -196,13 +196,13 @@
ptr = new_bucket(ht, key, klen);
ptr->next = NULL;
ptr->data = (void *) data;
- ht->table[val] = ptr;
+ ht->table[khash] = ptr;
ht->items++;
return ht;
}
DBGF("INUSE %s, ", key);
- for (ptr = ht->table[val]; NULL != ptr; ptr = ptr->next) {
+ for (ptr = ht->table[khash]; NULL != ptr; ptr = ptr->next) {
DBGF("%s, ", ptr->key);
if (strcmp(key, ptr->key) == 0) {
trurl_die("n_hash_insert: key '%s' %s already in table\n",
@@ -213,8 +213,8 @@
ptr = new_bucket(ht, key, klen);
ptr->data = (void *) data;
- ptr->next = ht->table[val];
- ht->table[val] = ptr;
+ ptr->next = ht->table[khash];
+ ht->table[khash] = ptr;
ht->items++;
return ht;
@@ -222,9 +222,10 @@
tn_hash *n_hash_insert(tn_hash *ht, const char *key, const void *data)
{
- return n_hash_put(ht, key, data, 0);
+ return n_hash_put(ht, key, 0, 0, data, 0);
}
+
tn_hash *n_hash_replace(tn_hash *ht, const char *key, const void *data)
{
if (ht->flags & TN_HASH_NOREPLACE) {
@@ -232,5 +233,12 @@
" \"non-replace\" hash table");
return NULL;
}
- return n_hash_put(ht, key, data, 1);
+ return n_hash_put(ht, key, 0, 0, data, 1);
+}
+
+
+tn_hash *n_hash_insert_ex(tn_hash *ht, const char *key, int klen, unsigned khash,
+ const void *data)
+{
+ return n_hash_put(ht, key, klen, khash, data, 0);
}
================================================================
Index: poldek/trurlib/n_hash_stats.c
diff -u poldek/trurlib/n_hash_stats.c:1.3 poldek/trurlib/n_hash_stats.c:1.4
--- poldek/trurlib/n_hash_stats.c:1.3 Tue Jun 22 20:57:31 2004
+++ poldek/trurlib/n_hash_stats.c Thu Jul 12 22:46:26 2007
@@ -31,8 +31,15 @@
deep = 1;
- for (tmp = ht->table[i]->next; tmp != NULL; tmp = tmp->next)
+ //if (ht->table[i]->next)
+ // printf("coll %s, ", ht->table[i]->key);
+
+ for (tmp = ht->table[i]->next; tmp != NULL; tmp = tmp->next) {
+ //printf("%s, ", tmp->key);
deep++;
+ }
+ //if (ht->table[i]->next)
+ // printf("\n");
if (deep > 1) {
ncolls++;
================================================================
Index: poldek/trurlib/n_hash_new.c
diff -u poldek/trurlib/n_hash_new.c:1.12 poldek/trurlib/n_hash_new.c:1.13
--- poldek/trurlib/n_hash_new.c:1.12 Sat Aug 19 19:34:19 2006
+++ poldek/trurlib/n_hash_new.c Thu Jul 12 22:46:26 2007
@@ -67,30 +67,52 @@
return n_hash_new2(na, size, freefn);
}
+/* djb hash */
# define CDB_HASHSTART 5381
int n_hash_dohash(const tn_hash *ht, const char *s, int *slen)
{
- register unsigned int v, n;
-
+ register unsigned int v;
+ const char *ss = s;
+
if (ht->hash_fn)
return ht->hash_fn(s) % ht->size;
-
-
+
v = CDB_HASHSTART;
- n = 0;
while (*s) {
v += (v << 5);
- v ^= *s;
+ v ^= (unsigned)*s;
s++;
- n++;
}
+
if (slen)
- *slen = n;
- //v += n;
+ *slen = s - ss;
+
return v & (ht->size - 1);
}
+#if 0 /* disabled */
+/*
+ FNV hash (see http://www.isthe.com/chongo/tech/comp/fnv)
+ A bit slower and gives a bit lower collision rate than djb's
+*/
+int n_hash_dohash(const tn_hash *ht, const char *s, int *slen)
+{
+ register unsigned v = 0;
+ const char *ss = s;
+
+ while (*s) {
+ /* xor the bottom with the current octet */
+ v ^= (unsigned)*s++;
+ // v += (v<<1) + (v<<4) + (v<<7) + (v<<8) + (v<<24);
+ v *= 0x01000193;
+ }
+
+ if (slen)
+ *slen = s - ss;
+ return v & (ht->size - 1);
+}
+#endif
int n_hash_size(const tn_hash *ht)
{
================================================================
Index: poldek/trurlib/include/trurl/nhash.h
diff -u poldek/trurlib/include/trurl/nhash.h:1.13 poldek/trurlib/include/trurl/nhash.h:1.14
--- poldek/trurlib/include/trurl/nhash.h:1.13 Fri Jul 23 18:15:54 2004
+++ poldek/trurlib/include/trurl/nhash.h Thu Jul 12 22:46:26 2007
@@ -35,37 +35,47 @@
if filled more than 80% */
#define TN_HASH_NOREPLACE (1 << 3) /* don't check for duplicate keys
while inserting; use with care! */
-int n_hash_ctl(tn_hash *ht, unsigned int flags);
-
-//int n_hash_ctl_bktallocfn(tn_hash *ht, );
+int n_hash_ctl(tn_hash *ht, unsigned int flags);
/* Removes all entries */
void n_hash_clean(tn_hash *ht);
/*
-** Inserts a pointer to 'data' in the table, with a copy of 'key'
-** (if TN_HASH_NOCPKEY not set) as its key. Note that this makes
-** a copy of the key, but NOT of the associated data.
+ Inserts a pointer to 'data' in the table, with a copy of 'key'
+ (if TN_HASH_NOCPKEY not set) as its key. Note that this makes
+ a copy of the key, but NOT of the associated data.
*/
tn_hash *n_hash_insert(tn_hash *ht, const char *key, const void *data);
+
tn_hash *n_hash_replace(tn_hash *ht, const char *key, const void *data);
+
/*
-** Returns a pointer to the data associated with a key.
+ Returns a pointer to the data associated with a key.
*/
-
void *n_hash_get(const tn_hash *ht, const char *key);
+int n_hash_exists(const tn_hash *ht, const char *key);
+
+
/*
-** If the key has not been inserted in the table, returns 0,
-** otherwise returns 1.
-*/
+ lower level insert / exists pair to avoid double computation of key hash
+ */
+void *n_hash_get_ex(const tn_hash *ht,
+ const char *key, int *klen, unsigned *khash);
+
+int n_hash_exists_ex(const tn_hash *ht,
+ const char *key, int *klen, unsigned *khash);
+
+tn_hash *n_hash_insert_ex(tn_hash *ht,
+ const char *key, int klen, unsigned khash,
+ const void *data);
+
-int n_hash_exists(const tn_hash *ht, const char *key);
/*
** Deletes an entry from the table. Returns a pointer to the data that
================================================================
---- CVS-web:
http://cvs.pld-linux.org/poldek/trurlib/libtrurl.sym?r1=1.3&r2=1.4&f=u
http://cvs.pld-linux.org/poldek/trurlib/n_hash_get.c?r1=1.3&r2=1.4&f=u
http://cvs.pld-linux.org/poldek/trurlib/n_hash_int.h?r1=1.9&r2=1.10&f=u
http://cvs.pld-linux.org/poldek/trurlib/n_hash_put.c?r1=1.7&r2=1.8&f=u
http://cvs.pld-linux.org/poldek/trurlib/n_hash_stats.c?r1=1.3&r2=1.4&f=u
http://cvs.pld-linux.org/poldek/trurlib/n_hash_new.c?r1=1.12&r2=1.13&f=u
http://cvs.pld-linux.org/poldek/trurlib/include/trurl/nhash.h?r1=1.13&r2=1.14&f=u
More information about the pld-cvs-commit
mailing list