Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 <blees@dcon.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Karsten Blees authored and Junio C Hamano committed Jul 7, 2014
1 parent aa420c4 commit ab73a9d
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 18 deletions.
14 changes: 14 additions & 0 deletions Documentation/technical/api-hashmap.txt
Expand Up @@ -118,6 +118,20 @@ hashmap_entry) that has at least been initialized with the proper hash code
If an entry with matching hash code is found, `key` and `keydata` are passed
to `hashmap_cmp_fn` to decide whether the entry matches the key.

`void *hashmap_get_from_hash(const struct hashmap *map, unsigned int hash, const void *keydata)`::

Returns the hashmap entry for the specified hash code and key data,
or NULL if not found.
+
`map` is the hashmap structure.
+
`hash` is the hash code of the entry to look up.
+
If an entry with matching hash code is found, `keydata` is passed to
`hashmap_cmp_fn` to decide whether the entry matches the key. The
`entry_or_key` parameter points to a bogus hashmap_entry structure that
should not be used in the comparison.

`void *hashmap_get_next(const struct hashmap *map, const void *entry)`::

Returns the next equal hashmap entry, or NULL if not found. This can be
Expand Down
4 changes: 1 addition & 3 deletions builtin/describe.c
Expand Up @@ -58,9 +58,7 @@ static int commit_name_cmp(const struct commit_name *cn1,

static inline struct commit_name *find_commit_name(const unsigned char *peeled)
{
struct commit_name key;
hashmap_entry_init(&key, sha1hash(peeled));
return hashmap_get(&names, &key, peeled);
return hashmap_get_from_hash(&names, sha1hash(peeled), peeled);
}

static int replace_name(struct commit_name *e,
Expand Down
7 changes: 3 additions & 4 deletions diffcore-rename.c
Expand Up @@ -257,15 +257,14 @@ static int find_identical_files(struct hashmap *srcs,
int renames = 0;

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

/*
* Find the best source match for specified destination.
*/
best = NULL;
hashmap_entry_init(&dst, hash_filespec(target));
for (p = hashmap_get(srcs, &dst, NULL); p; p = hashmap_get_next(srcs, p)) {
p = hashmap_get_from_hash(srcs, hash_filespec(target), NULL);
for (; p; p = hashmap_get_next(srcs, p)) {
int score;
struct diff_filespec *source = p->filespec;

Expand Down
8 changes: 8 additions & 0 deletions hashmap.h
Expand Up @@ -68,6 +68,14 @@ extern void *hashmap_put(struct hashmap *map, void *entry);
extern void *hashmap_remove(struct hashmap *map, const void *key,
const void *keydata);

static inline void *hashmap_get_from_hash(const struct hashmap *map,
unsigned int hash, const void *keydata)
{
struct hashmap_entry key;
hashmap_entry_init(&key, hash);
return hashmap_get(map, &key, keydata);
}

/* hashmap_iter functions */

extern void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter);
Expand Down
5 changes: 2 additions & 3 deletions name-hash.c
Expand Up @@ -213,12 +213,11 @@ struct cache_entry *index_dir_exists(struct index_state *istate, const char *nam
struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase)
{
struct cache_entry *ce;
struct hashmap_entry key;

lazy_init_name_hash(istate);

hashmap_entry_init(&key, memihash(name, namelen));
ce = hashmap_get(&istate->name_hash, &key, NULL);
ce = hashmap_get_from_hash(&istate->name_hash,
memihash(name, namelen), NULL);
while (ce) {
if (same_name(ce, name, namelen, icase))
return ce;
Expand Down
11 changes: 3 additions & 8 deletions test-hashmap.c
Expand Up @@ -115,9 +115,8 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)

for (j = 0; j < rounds; j++) {
for (i = 0; i < TEST_SIZE; i++) {
struct hashmap_entry key;
hashmap_entry_init(&key, hashes[i]);
hashmap_get(&map, &key, entries[i]->key);
hashmap_get_from_hash(&map, hashes[i],
entries[i]->key);
}
}

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

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

/* setup static key */
struct hashmap_entry key;
hashmap_entry_init(&key, hash);

/* lookup entry in hashmap */
entry = hashmap_get(&map, &key, p1);
entry = hashmap_get_from_hash(&map, hash, p1);

/* print result */
if (!entry)
Expand Down

0 comments on commit ab73a9d

Please sign in to comment.