Skip to content

Commit 0607e10

Browse files
jeffhostetlergitster
authored andcommitted
hashmap: add disallow_rehash setting
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f75619b commit 0607e10

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

hashmap.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,19 @@ static inline unsigned int bucket(const struct hashmap *map,
104104
return key->hash & (map->tablesize - 1);
105105
}
106106

107+
int hashmap_bucket(const struct hashmap *map, unsigned int hash)
108+
{
109+
return hash & (map->tablesize - 1);
110+
}
111+
107112
static void rehash(struct hashmap *map, unsigned int newsize)
108113
{
109114
unsigned int i, oldsize = map->tablesize;
110115
struct hashmap_entry **oldtable = map->table;
111116

117+
if (map->disallow_rehash)
118+
return;
119+
112120
alloc_table(map, newsize);
113121
for (i = 0; i < oldsize; i++) {
114122
struct hashmap_entry *e = oldtable[i];
@@ -141,7 +149,9 @@ void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function,
141149
size_t initial_size)
142150
{
143151
unsigned int size = HASHMAP_INITIAL_SIZE;
144-
map->size = 0;
152+
153+
memset(map, 0, sizeof(*map));
154+
145155
map->cmpfn = equals_function ? equals_function : always_equal;
146156

147157
/* calculate initial table size and allocate the table */

hashmap.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct hashmap {
3939
struct hashmap_entry **table;
4040
hashmap_cmp_fn cmpfn;
4141
unsigned int size, tablesize, grow_at, shrink_at;
42+
unsigned disallow_rehash : 1;
4243
};
4344

4445
struct hashmap_iter {
@@ -77,6 +78,29 @@ static inline void *hashmap_get_from_hash(const struct hashmap *map,
7778
return hashmap_get(map, &key, keydata);
7879
}
7980

81+
int hashmap_bucket(const struct hashmap *map, unsigned int hash);
82+
83+
/*
84+
* Disallow/allow rehashing of the hashmap.
85+
* This is useful if the caller knows that the hashmap
86+
* needs multi-threaded access. The caller is still
87+
* required to guard/lock searches and inserts in a
88+
* manner appropriate to their usage. This simply
89+
* prevents the table from being unexpectedly re-mapped.
90+
*
91+
* If is up to the caller to ensure that the hashmap is
92+
* initialized to a reasonable size to prevent poor
93+
* performance.
94+
*
95+
* When value=1, prevent future rehashes on adds and deleted.
96+
* When value=0, allow future rehahses. This DOES NOT force
97+
* a rehash now.
98+
*/
99+
static inline void hashmap_disallow_rehash(struct hashmap *map, unsigned value)
100+
{
101+
map->disallow_rehash = value;
102+
}
103+
80104
/* hashmap_iter functions */
81105

82106
extern void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter);

0 commit comments

Comments
 (0)