Skip to content

Commit ab73a9d

Browse files
kbleesgitster
authored andcommitted
hashmap: add simplified hashmap_get_from_hash() API
Hashmap entries are typically looked up by just a key. The hashmap_get() API expects an initialized entry structure instead, to support compound keys. This flexibility is currently only needed by find_dir_entry() in name-hash.c (and compat/win32/fscache.c in the msysgit fork). All other (currently five) call sites of hashmap_get() have to set up a near emtpy entry structure, resulting in duplicate code like this: struct hashmap_entry keyentry; hashmap_entry_init(&keyentry, hash(key)); return hashmap_get(map, &keyentry, key); Add a hashmap_get_from_hash() API that allows hashmap lookups by just specifying the key and its hash code, i.e.: return hashmap_get_from_hash(map, hash(key), key); Signed-off-by: Karsten Blees <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent aa420c4 commit ab73a9d

File tree

6 files changed

+31
-18
lines changed

6 files changed

+31
-18
lines changed

Documentation/technical/api-hashmap.txt

+14
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ hashmap_entry) that has at least been initialized with the proper hash code
118118
If an entry with matching hash code is found, `key` and `keydata` are passed
119119
to `hashmap_cmp_fn` to decide whether the entry matches the key.
120120

121+
`void *hashmap_get_from_hash(const struct hashmap *map, unsigned int hash, const void *keydata)`::
122+
123+
Returns the hashmap entry for the specified hash code and key data,
124+
or NULL if not found.
125+
+
126+
`map` is the hashmap structure.
127+
+
128+
`hash` is the hash code of the entry to look up.
129+
+
130+
If an entry with matching hash code is found, `keydata` is passed to
131+
`hashmap_cmp_fn` to decide whether the entry matches the key. The
132+
`entry_or_key` parameter points to a bogus hashmap_entry structure that
133+
should not be used in the comparison.
134+
121135
`void *hashmap_get_next(const struct hashmap *map, const void *entry)`::
122136

123137
Returns the next equal hashmap entry, or NULL if not found. This can be

builtin/describe.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ static int commit_name_cmp(const struct commit_name *cn1,
5858

5959
static inline struct commit_name *find_commit_name(const unsigned char *peeled)
6060
{
61-
struct commit_name key;
62-
hashmap_entry_init(&key, sha1hash(peeled));
63-
return hashmap_get(&names, &key, peeled);
61+
return hashmap_get_from_hash(&names, sha1hash(peeled), peeled);
6462
}
6563

6664
static int replace_name(struct commit_name *e,

diffcore-rename.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -257,15 +257,14 @@ static int find_identical_files(struct hashmap *srcs,
257257
int renames = 0;
258258

259259
struct diff_filespec *target = rename_dst[dst_index].two;
260-
struct file_similarity *p, *best, dst;
260+
struct file_similarity *p, *best = NULL;
261261
int i = 100, best_score = -1;
262262

263263
/*
264264
* Find the best source match for specified destination.
265265
*/
266-
best = NULL;
267-
hashmap_entry_init(&dst, hash_filespec(target));
268-
for (p = hashmap_get(srcs, &dst, NULL); p; p = hashmap_get_next(srcs, p)) {
266+
p = hashmap_get_from_hash(srcs, hash_filespec(target), NULL);
267+
for (; p; p = hashmap_get_next(srcs, p)) {
269268
int score;
270269
struct diff_filespec *source = p->filespec;
271270

hashmap.h

+8
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ extern void *hashmap_put(struct hashmap *map, void *entry);
6868
extern void *hashmap_remove(struct hashmap *map, const void *key,
6969
const void *keydata);
7070

71+
static inline void *hashmap_get_from_hash(const struct hashmap *map,
72+
unsigned int hash, const void *keydata)
73+
{
74+
struct hashmap_entry key;
75+
hashmap_entry_init(&key, hash);
76+
return hashmap_get(map, &key, keydata);
77+
}
78+
7179
/* hashmap_iter functions */
7280

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

name-hash.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,11 @@ struct cache_entry *index_dir_exists(struct index_state *istate, const char *nam
213213
struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase)
214214
{
215215
struct cache_entry *ce;
216-
struct hashmap_entry key;
217216

218217
lazy_init_name_hash(istate);
219218

220-
hashmap_entry_init(&key, memihash(name, namelen));
221-
ce = hashmap_get(&istate->name_hash, &key, NULL);
219+
ce = hashmap_get_from_hash(&istate->name_hash,
220+
memihash(name, namelen), NULL);
222221
while (ce) {
223222
if (same_name(ce, name, namelen, icase))
224223
return ce;

test-hashmap.c

+3-8
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,8 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
115115

116116
for (j = 0; j < rounds; j++) {
117117
for (i = 0; i < TEST_SIZE; i++) {
118-
struct hashmap_entry key;
119-
hashmap_entry_init(&key, hashes[i]);
120-
hashmap_get(&map, &key, entries[i]->key);
118+
hashmap_get_from_hash(&map, hashes[i],
119+
entries[i]->key);
121120
}
122121
}
123122

@@ -199,12 +198,8 @@ int main(int argc, char *argv[])
199198

200199
} else if (!strcmp("get", cmd) && l1) {
201200

202-
/* setup static key */
203-
struct hashmap_entry key;
204-
hashmap_entry_init(&key, hash);
205-
206201
/* lookup entry in hashmap */
207-
entry = hashmap_get(&map, &key, p1);
202+
entry = hashmap_get_from_hash(&map, hash, p1);
208203

209204
/* print result */
210205
if (!entry)

0 commit comments

Comments
 (0)