remove debug messages
[archipelago] / xseg / xtypes / xhash.c
index 4c9e337..f174a1e 100644 (file)
 
 #define PERTURB_SHIFT 5
 
+static inline xhashidx hash_int(xhashidx key)
+{
+       return key;
+}
+
+static inline int cmp_int(xhashidx key1, xhashidx key2)
+{
+       return (key1 == key2);
+}
+
+static inline xhashidx hash_string(xhashidx key) 
+{
+       //assume a valid NULL terminated string
+       
+       //function to access key if in container
+       char *string = (char *) key;
+       unsigned int i, len = strlen(string);
+       xhashidx hv = string[0] << 7;
+       for (i = 1; i <= len; i++) {
+               hv = (hv * 1000003) ^ string[i];
+       }
+       if (hv == Noxhashidx)
+               hv = Noxhashidx -1;
+
+//     XSEGLOG("String %s (%lx). Hash value: %llu",
+//                     string, string, hv);
+       return hv; 
+}
+
+static inline int cmp_string(xhashidx key1, xhashidx key2)
+{
+       char *string1 = (char *) key1;
+       char *string2 = (char *) key2;
+       int value = !strcmp(string1, string2);
+//     XSEGLOG("String1 %s (%lx), string2: %s(%lx), r: %d",
+//                     string1, (unsigned long) string1,
+//                     string2, (unsigned long) string2,
+//                     value);
+
+       return (value);
+}
+
+typedef int (*xhash_cmp_fun_t)(xhashidx key1, xhashidx key2);
+typedef xhashidx (*xhash_hash_fun_t)(xhashidx key);
+
+struct types_functions {
+//     int (*cmp_fun)(xhashidx key1, xhashidx key2);
+//     xhashidx (*hash_fun)(xhashidx key);
+       xhash_cmp_fun_t cmp_fun;
+       xhash_hash_fun_t hash_fun;
+};
+
+static struct types_functions types_fun[] = {
+       { .cmp_fun = cmp_int, .hash_fun = hash_int },
+       { .cmp_fun = cmp_string, .hash_fun = hash_string }
+};
+
+
 static inline void
 set_dummy_key(xhash_t *xhash, xhashidx idx)
 {
@@ -130,7 +188,8 @@ assert_kv(xhashidx k, xhashidx v)
 */
 
 void
-xhash_init__(xhash_t *xhash, xhashidx size_shift, xhashidx minsize_shift, bool vals)
+xhash_init__(xhash_t *xhash, xhashidx size_shift, xhashidx minsize_shift, 
+               enum xhash_type type, bool vals)
 {
     xhashidx nr_items = 1UL << size_shift;
     xhashidx *kvs = (xhashidx *) ((char *) xhash + sizeof(struct xhash));
@@ -157,6 +216,7 @@ out:
     xhash->dummies = xhash->used = 0;
     xhash->size_shift = size_shift;
     xhash->minsize_shift = minsize_shift;
+    xhash->type = type;
 
     ZEROSTAT(xhash->inserts);
     ZEROSTAT(xhash->deletes);
@@ -175,7 +235,9 @@ get_alloc_size(xhashidx size_shift, bool vals)
 
 
 xhash_t *
-xhash_new__(xhashidx size_shift, xhashidx minsize_shift, bool vals) {
+xhash_new__(xhashidx size_shift, xhashidx minsize_shift, 
+               enum xhash_type type, bool vals) 
+{
     struct xhash *xhash;
     xhash = xtypes_malloc(get_alloc_size(size_shift, vals));
     if (!xhash) {
@@ -183,7 +245,7 @@ xhash_new__(xhashidx size_shift, xhashidx minsize_shift, bool vals) {
        return NULL;
     }
 
-    xhash_init__(xhash, size_shift, minsize_shift, vals);
+    xhash_init__(xhash, size_shift, minsize_shift, type, vals);
     
     return xhash;
 }
@@ -192,15 +254,18 @@ xhash_new__(xhashidx size_shift, xhashidx minsize_shift, bool vals) {
 xhash_t *
 xhash_resize__(struct xhash *xhash, xhashidx new_size_shift, bool vals)
 {
-    return xhash_new__(new_size_shift, xhash->minsize_shift, vals);
+    return xhash_new__(new_size_shift, xhash->minsize_shift, xhash->type, vals);
 }
 
 int
 xhash_delete__(xhash_t *xhash, xhashidx key, bool vals)
 {
-    xhashidx perturb = key;
+//    XSEGLOG("Deleting %lx", key);
+    xhash_cmp_fun_t cmp_fun = types_fun[xhash->type].cmp_fun;
+    xhash_hash_fun_t hash_fun = types_fun[xhash->type].hash_fun; 
+    xhashidx perturb = hash_fun(key);
     xhashidx mask = xhash_size(xhash)-1;
-    xhashidx idx = key & mask;
+    xhashidx idx = hash_fun(key) & mask;
     xhashidx *kvs = xhash_kvs(xhash);
 
     for (;;) {
@@ -208,7 +273,7 @@ xhash_delete__(xhash_t *xhash, xhashidx key, bool vals)
             return -2;
         }
 
-        if ( !item_dummy(xhash, idx, vals) && kvs[idx] == key){
+        if ( !item_dummy(xhash, idx, vals) && cmp_fun(kvs[idx],key)){
             INCSTAT(xhash->deletes);
             set_dummy_item(xhash, idx, vals);
             xhash->dummies++;
@@ -283,9 +348,9 @@ xhash_get_alloc_size(xhashidx size_shift)
 }
 
 xhash_t *
-xhash_new(xhashidx minsize_shift)
+xhash_new(xhashidx minsize_shift, enum xhash_type type)
 {
-    return xhash_new__(minsize_shift, minsize_shift, true);
+    return xhash_new__(minsize_shift, minsize_shift, type, true);
 }
 
 void xhash_free(struct xhash *xhash)
@@ -293,9 +358,9 @@ void xhash_free(struct xhash *xhash)
     xtypes_free(xhash);
 }
 
-void xhash_init(struct xhash *xhash, xhashidx minsize_shift)
+void xhash_init(struct xhash *xhash, xhashidx minsize_shift, enum xhash_type type)
 {
-       xhash_init__(xhash, minsize_shift, minsize_shift, true);
+       xhash_init__(xhash, minsize_shift, minsize_shift, type, true);
 }
 
 /*
@@ -325,11 +390,13 @@ xhash_grow_check(xhash_t *xhash)
 
 #define PHASH_UPDATE(xhash, key, val, vals_flag)      \
 {                                                     \
-    xhashidx size = 1UL<<(xhash->size_shift);             \
-    xhashidx perturb = key;                               \
-    xhashidx mask = size-1;                               \
-    xhashidx idx = key & mask;                            \
-    xhashidx *kvs = xhash_kvs(xhash);                      \
+    xhash_cmp_fun_t cmp_fun = types_fun[xhash->type].cmp_fun;         \
+    xhash_hash_fun_t hash_fun = types_fun[xhash->type].hash_fun;       \
+    xhashidx size = 1UL<<(xhash->size_shift);         \
+    xhashidx perturb = hash_fun(key);                           \
+    xhashidx mask = size-1;                           \
+    xhashidx idx = hash_fun(key) & mask;              \
+    xhashidx *kvs = xhash_kvs(xhash);                 \
                                                       \
     INCSTAT(xhash->inserts);                          \
     for (;;) {                                        \
@@ -337,7 +404,7 @@ xhash_grow_check(xhash_t *xhash)
              PHUPD_SET__(xhash, idx, key, val);       \
              break;                                   \
         }                                             \
-        if (kvs[idx] == key){                  \
+        if (cmp_fun(kvs[idx], key)){                  \
             PHUPD_UPDATE__(xhash, idx, key, val);     \
             break;                                    \
         }                                             \
@@ -356,6 +423,7 @@ set_val(xhash_t *p, xhashidx idx, xhashidx key, xhashidx val)
     xhashidx *vals = xhash_vals(p);
     kvs[idx] = key;
     vals[idx] = val;
+    //XSEGLOG("Seting idx %llu to key: %lx, val: %lx", idx, key, val);
 }
 
 void static inline xhash_upd_set(xhash_t *p, xhashidx idx, xhashidx key, xhashidx val)
@@ -367,6 +435,7 @@ void static inline xhash_upd_set(xhash_t *p, xhashidx idx, xhashidx key, xhashid
     p->used++;
     kvs[idx] = key;
     vals[idx] = val;
+    //XSEGLOG("Seting idx %llu to key: %lx, val: %lx", idx, key, val);
 }
 
 static inline void
@@ -378,6 +447,7 @@ inc_val(xhash_t *p, xhashidx idx, xhashidx val)
 
 void xhash_insert__(struct xhash *xhash, xhashidx key, xhashidx val)
 {
+    //XSEGLOG("inserting %lx", key);
     //fprintf(stderr, "insert: (%lu,%lu)\n", key, val);
     #define PHUPD_UPDATE__(_p, _i, _k, _v) set_val(_p, _i, _k, _v)
     #define PHUPD_SET__(_p, _i, _k, _v)    xhash_upd_set(_p, _i, _k, _v)
@@ -415,12 +485,13 @@ int xhash_freql_update(struct xhash *xhash, xhashidx key, xhashidx val)
 xhash_t *
 xhash_resize(xhash_t *xhash, xhashidx new_size_shift, xhash_t *new)
 {
+    //XSEGLOG("Resizing xhash from %llu to %llu", xhash->size_shift, new_size_shift);
     xhashidx i;
     int f = !!new;
     if (!f)
-        new = xhash_new__(new_size_shift, xhash->minsize_shift, true);
+        new = xhash_new__(new_size_shift, xhash->minsize_shift, xhash->type, true);
     else
-        xhash_init__(new, new_size_shift, xhash->minsize_shift, true);
+        xhash_init__(new, new_size_shift, xhash->minsize_shift, xhash->type, true);
 
     if (!new)
            return NULL;
@@ -464,19 +535,24 @@ int xhash_delete(struct xhash *xhash, xhashidx key)
 
 int xhash_lookup__(xhash_t *xhash, xhashidx key, xhashidx *idx_ret, bool vals)
 {
+    //XSEGLOG("looking up %lx", key);
+    xhash_cmp_fun_t cmp_fun = types_fun[xhash->type].cmp_fun;
+    xhash_hash_fun_t hash_fun = types_fun[xhash->type].hash_fun; 
     xhashidx size_shift = xhash->size_shift;
-    xhashidx size = (xhashidx)1<<size_shift;
-    xhashidx perturb = key;
+    xhashidx size = (1UL)<<size_shift;
+    xhashidx perturb = hash_fun(key);
     xhashidx mask = size-1;
-    xhashidx idx = key & mask;
+    xhashidx idx = hash_fun(key) & mask;
     xhashidx *kvs = xhash_kvs(xhash);
 
     INCSTAT(xhash->lookups);
     for (;;) {
+       //XSEGLOG("size %llu, perturb %llu idx %llu mask %llu",
+       //          size, perturb, idx, mask);          
         if ( item_unused(xhash, idx, vals) )
             return -XHASH_EEXIST;
 
-        if ( !item_dummy(xhash, idx, vals) && kvs[idx] == key){
+        if ( !item_dummy(xhash, idx, vals) && cmp_fun(kvs[idx],key)){
             *idx_ret = idx;
             return 0;
         }
@@ -498,6 +574,7 @@ int xhash_lookup(struct xhash *xhash, xhashidx key, xhashidx *val)
     return ret;
 }
 
+//FIXME iteration broken
 void
 xhash_iter_init(xhash_t *xhash, xhash_iter_t *pi)
 {
@@ -577,7 +654,7 @@ int main(int argc, char **argv)
     xhashidx key, val;
     int ret;
 
-    ph = xhash_new(2);
+    ph = xhash_new(2, INTEGER);
 
     for (;;){
         s = fgets(buf, BUFLEN-1, stdin);
@@ -856,4 +933,10 @@ int main(int argc, char **argv)
 #endif
 
 #endif //if 0
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#include <xtypes/xhash_exports.h>
+#endif
+
 // vim:expandtab:tabstop=8:shiftwidth=4:softtabstop=4