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.
isl_equalities.c \
isl_equalities.h \
isl_gmp.c \
+ isl_hash.c \
isl_input.c \
isl_input_omega.c \
isl_input_omega.h \
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 \
--- /dev/null
+#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
#ifndef ISL_INT_H
#define ISL_INT_H
-#include <isl_stdint.h>
+#include <isl_hash.h>
#include <string.h>
#include <gmp.h>
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
--- /dev/null
+#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;
+}
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]);
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);
}