introduce isl_hash_table and move hashing declarations into include/isl_hash.h
authorSven Verdoolaege <skimo@kotnet.org>
Fri, 5 Dec 2008 18:06:17 +0000 (19:06 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Sun, 14 Dec 2008 16:26:37 +0000 (17:26 +0100)
This isl_hash_table will be used in the next commit.
This commit also changes the calling convention of isl_hash_init
to be more consistent with the other isl_hash_ functions/macros.

Makefile.am
include/isl_hash.h [new file with mode: 0644]
include/isl_int.h
isl_hash.c [new file with mode: 0644]
isl_map.c
isl_seq.c

index df2318f..b4b5349 100644 (file)
@@ -50,6 +50,7 @@ libisl_la_SOURCES = \
        isl_equalities.c \
        isl_equalities.h \
        isl_gmp.c \
+       isl_hash.c \
        isl_input.c \
        isl_input_omega.c \
        isl_input_omega.h \
@@ -93,6 +94,7 @@ pkginclude_HEADERS = \
        include/isl_constraint.h \
        include/isl_dim.h \
        include/isl_int.h \
+       include/isl_hash.h \
        include/isl_list.h \
        include/isl_lp.h \
        include/isl_lp_piplib.h \
diff --git a/include/isl_hash.h b/include/isl_hash.h
new file mode 100644 (file)
index 0000000..b850751
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef ISL_HASH_H
+#define ISL_HASH_H
+
+#include <isl_stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define isl_hash_init()                (2166136261u)
+#define isl_hash_byte(h,b)     do {                                    \
+                                       h *= 16777619;                  \
+                                       h ^= b;                         \
+                               } while(0)
+#define isl_hash_hash(h,h2)                                            \
+       do {                                                            \
+               isl_hash_byte(h, (h2) & 0xFF);                          \
+               isl_hash_byte(h, ((h2) >> 8) & 0xFF);                   \
+               isl_hash_byte(h, ((h2) >> 16) & 0xFF);                  \
+               isl_hash_byte(h, ((h2) >> 24) & 0xFF);                  \
+       } while(0)
+#define isl_hash_bits(h,bits)                                          \
+       ((bits) == 32) ? (h) :                                          \
+       ((bits) >= 16) ?                                                \
+             ((h) >> (bits)) ^ ((h) & (((uint32_t)1 << (bits)) - 1)) : \
+             (((h) >> (bits)) ^ (h)) & (((uint32_t)1 << (bits)) - 1)
+
+uint32_t isl_hash_string(uint32_t hash, const char *s);
+
+struct isl_hash_table_entry
+{
+       uint32_t  hash;
+       void     *data;
+};
+
+struct isl_hash_table {
+       int    bits;
+       int    n;
+       struct isl_hash_table_entry *entries;
+};
+
+struct isl_ctx;
+
+int isl_hash_table_init(struct isl_ctx *ctx, struct isl_hash_table *table,
+                       int init_bits);
+void isl_hash_table_clear(struct isl_hash_table *table);
+struct isl_hash_table_entry *isl_hash_table_find(struct isl_ctx *ctx,
+                               struct isl_hash_table *table,
+                               uint32_t key_hash,
+                               int (*eq)(const void *entry, const void *val),
+                               const void *val, int reserve);
+void isl_hash_table_remove(struct isl_ctx *ctx,
+                               struct isl_hash_table *table,
+                               struct isl_hash_table_entry *entry);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
index 1326664..ddb2422 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef ISL_INT_H
 #define ISL_INT_H
 
-#include <isl_stdint.h>
+#include <isl_hash.h>
 #include <string.h>
 #include <gmp.h>
 
@@ -84,24 +84,6 @@ typedef mpz_t        isl_int;
 uint32_t isl_gmp_hash(mpz_t v, uint32_t hash);
 #define isl_int_hash(v,h)      isl_gmp_hash(v,h)
 
-#define isl_hash_init(h)       (h = 2166136261u)
-#define isl_hash_byte(h,b)     do {                                    \
-                                       h *= 16777619;                  \
-                                       h ^= b;                         \
-                               } while(0)
-#define isl_hash_hash(h,h2)                                            \
-       do {                                                            \
-               isl_hash_byte(h, (h2) & 0xFF);                          \
-               isl_hash_byte(h, ((h2) >> 8) & 0xFF);                   \
-               isl_hash_byte(h, ((h2) >> 16) & 0xFF);                  \
-               isl_hash_byte(h, ((h2) >> 24) & 0xFF);                  \
-       } while(0)
-#define isl_hash_bits(h,bits)                                          \
-       ((bits) == 32) ? (h) :                                          \
-       ((bits) >= 16) ?                                                \
-             ((h) >> (bits)) ^ ((h) & (((uint32_t)1 << (bits)) - 1)) : \
-             (((h) >> (bits)) ^ (h)) & (((uint32_t)1 << (bits)) - 1)
-
 #if defined(__cplusplus)
 }
 #endif
diff --git a/isl_hash.c b/isl_hash.c
new file mode 100644 (file)
index 0000000..41076b8
--- /dev/null
@@ -0,0 +1,94 @@
+#include <stdlib.h>
+#include "isl_hash.h"
+#include "isl_ctx.h"
+
+uint32_t isl_hash_string(uint32_t hash, const char *s)
+{
+       for (; *s; s++)
+               isl_hash_byte(hash, *s);
+       return hash;
+}
+
+int isl_hash_table_init(struct isl_ctx *ctx, struct isl_hash_table *table,
+                       int init_bits)
+{
+       size_t size;
+
+       if (!table)
+               return -1;
+
+       if (init_bits < 2)
+               init_bits = 2;
+       table->bits = init_bits;
+       table->n = 0;
+
+       size = 2 << table->bits;
+       table->entries = isl_calloc_array(ctx, struct isl_hash_table_entry,
+                                         size);
+       if (!table->entries)
+               return -1;
+
+       return 0;
+}
+
+void isl_hash_table_clear(struct isl_hash_table *table)
+{
+       if (!table)
+               return;
+       free(table->entries);
+}
+
+struct isl_hash_table_entry *isl_hash_table_find(struct isl_ctx *ctx,
+                               struct isl_hash_table *table,
+                               uint32_t key_hash,
+                               int (*eq)(const void *entry, const void *val),
+                               const void *val, int reserve)
+{
+       size_t size;
+       uint32_t h, key_bits;
+
+       key_bits = isl_hash_bits(key_hash, table->bits);
+       size = 2 << table->bits;
+       for (h = key_bits; table->entries[h].data; h = (h+1) % size)
+               if (table->entries[h].hash == key_hash &&
+                   eq(table->entries[h].data, val))
+                       return &table->entries[h];
+
+       if (!reserve)
+               return NULL;
+
+       assert(4 * table->n < 3 * size); /* XXX */
+       table->n++;
+       table->entries[h].hash = key_hash;
+
+       return &table->entries[h];
+}
+
+void isl_hash_table_remove(struct isl_ctx *ctx,
+                               struct isl_hash_table *table,
+                               struct isl_hash_table_entry *entry)
+{
+       int h, h2, last_h;
+       size_t size;
+
+       if (!table || !entry)
+               return;
+
+       size = 2 << table->bits;
+       h = entry - table->entries;
+       isl_assert(ctx, h >= 0 && h < size, return);
+
+       for (h2 = h+1; table->entries[h2 % size].data; h2++) {
+               uint32_t bits = isl_hash_bits(table->entries[h2 % size].hash,
+                                               table->bits);
+               uint32_t offset = (size + bits - (h+1)) % size;
+               if (offset <= h2 - (h+1))
+                       continue;
+               *entry = table->entries[h2 % size];
+               h = h2;
+               entry = &table->entries[h % size];
+       }
+
+       entry->hash = 0;
+       entry->data = NULL;
+}
index d0aed0c..4719329 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -5301,7 +5301,7 @@ uint32_t isl_set_get_hash(struct isl_set *set)
        if (!set)
                return 0;
 
-       isl_hash_init(hash);
+       hash = isl_hash_init();
        for (i = 0; i < set->n; ++i) {
                uint32_t bset_hash;
                bset_hash = isl_basic_set_get_hash(set->p[i]);
index 50c5bd9..3923158 100644 (file)
--- a/isl_seq.c
+++ b/isl_seq.c
@@ -192,8 +192,7 @@ uint32_t isl_seq_hash(isl_int *p, unsigned len, uint32_t hash)
 
 uint32_t isl_seq_get_hash(isl_int *p, unsigned len)
 {
-       uint32_t hash;
-       isl_hash_init(hash);
+       uint32_t hash = isl_hash_init();
 
        return isl_seq_hash(p, len, hash);
 }