aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hashmap.c12
-rw-r--r--hashmap.h24
2 files changed, 35 insertions, 1 deletions
diff --git a/hashmap.c b/hashmap.c
index 93793cb95..7d1044eb5 100644
--- a/hashmap.c
+++ b/hashmap.c
@@ -104,11 +104,19 @@ static inline unsigned int bucket(const struct hashmap *map,
return key->hash & (map->tablesize - 1);
}
+int hashmap_bucket(const struct hashmap *map, unsigned int hash)
+{
+ return hash & (map->tablesize - 1);
+}
+
static void rehash(struct hashmap *map, unsigned int newsize)
{
unsigned int i, oldsize = map->tablesize;
struct hashmap_entry **oldtable = map->table;
+ if (map->disallow_rehash)
+ return;
+
alloc_table(map, newsize);
for (i = 0; i < oldsize; i++) {
struct hashmap_entry *e = oldtable[i];
@@ -141,7 +149,9 @@ void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function,
size_t initial_size)
{
unsigned int size = HASHMAP_INITIAL_SIZE;
- map->size = 0;
+
+ memset(map, 0, sizeof(*map));
+
map->cmpfn = equals_function ? equals_function : always_equal;
/* calculate initial table size and allocate the table */
diff --git a/hashmap.h b/hashmap.h
index 45eda693b..de6022a3a 100644
--- a/hashmap.h
+++ b/hashmap.h
@@ -39,6 +39,7 @@ struct hashmap {
struct hashmap_entry **table;
hashmap_cmp_fn cmpfn;
unsigned int size, tablesize, grow_at, shrink_at;
+ unsigned disallow_rehash : 1;
};
struct hashmap_iter {
@@ -77,6 +78,29 @@ static inline void *hashmap_get_from_hash(const struct hashmap *map,
return hashmap_get(map, &key, keydata);
}
+int hashmap_bucket(const struct hashmap *map, unsigned int hash);
+
+/*
+ * Disallow/allow rehashing of the hashmap.
+ * This is useful if the caller knows that the hashmap
+ * needs multi-threaded access. The caller is still
+ * required to guard/lock searches and inserts in a
+ * manner appropriate to their usage. This simply
+ * prevents the table from being unexpectedly re-mapped.
+ *
+ * If is up to the caller to ensure that the hashmap is
+ * initialized to a reasonable size to prevent poor
+ * performance.
+ *
+ * When value=1, prevent future rehashes on adds and deleted.
+ * When value=0, allow future rehahses. This DOES NOT force
+ * a rehash now.
+ */
+static inline void hashmap_disallow_rehash(struct hashmap *map, unsigned value)
+{
+ map->disallow_rehash = value;
+}
+
/* hashmap_iter functions */
extern void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter);