Skip to content

Commit

Permalink
hashmap: add disallow_rehash setting
Browse files Browse the repository at this point in the history
Teach hashmap to allow rehashes to be suppressed.
This is useful when hashmaps are accessed by multiple
threads.  It still requires the caller to properly
manage their locking.  This just prevents unexpected
rehashing during inserts and deletes.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
jeffhostetler authored and gitster committed Mar 22, 2017
1 parent f75619b commit 0607e10
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
12 changes: 11 additions & 1 deletion hashmap.c
Expand Up @@ -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];
Expand Down Expand Up @@ -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 */
Expand Down
24 changes: 24 additions & 0 deletions hashmap.h
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 0607e10

Please sign in to comment.