patch-ids: stop using a hand-rolled hashmap implementation

This change will use the hashmap from the hashmap.h to keep track of the patch_ids that have been encountered instead of using an internal implementation. This simplifies the implementation of the patch ids. Signed-off-by: Kevin Willford <kcwillford@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kevin Willford committed Jul 29, 2016 at 12:19 UTC dfb7a1b4d0dafd53bf3980b3bd90668bf8d2a27f
2 files changed +32 -61
patch-ids.c
+29 -57
@@ -16,90 +16,62 @@ int commit_patch_id(struct commit *commit, struct diff_options *options,
16 return diff_flush_patch_id(options, sha1);
17 }
18
19 -static const unsigned char *patch_id_access(size_t index, void *table)
19 +static int patch_id_cmp(struct patch_id *a,
20 + struct patch_id *b,
21 + void *keydata)
22 {
21 - struct patch_id **id_table = table;
22 - return id_table[index]->patch_id;
23 + return hashcmp(a->patch_id, b->patch_id);
24 }
25
25 -static int patch_pos(struct patch_id **table, int nr, const unsigned char *id)
26 -{
27 - return sha1_pos(id, table, nr, patch_id_access);
28 -}
29 -
30 -#define BUCKET_SIZE 190 /* 190 * 21 = 3990, with slop close enough to 4K */
31 -struct patch_id_bucket {
32 - struct patch_id_bucket *next;
33 - int nr;
34 - struct patch_id bucket[BUCKET_SIZE];
35 -};
36 -
26 int init_patch_ids(struct patch_ids *ids)
27 {
28 memset(ids, 0, sizeof(*ids));
29 diff_setup(&ids->diffopts);
30 DIFF_OPT_SET(&ids->diffopts, RECURSIVE);
31 diff_setup_done(&ids->diffopts);
32 + hashmap_init(&ids->patches, (hashmap_cmp_fn)patch_id_cmp, 256);
33 return 0;
34 }
35
36 int free_patch_ids(struct patch_ids *ids)
37 {
48 - struct patch_id_bucket *next, *patches;
49 -
50 - free(ids->table);
51 - for (patches = ids->patches; patches; patches = next) {
52 - next = patches->next;
53 - free(patches);
54 - }
38 + hashmap_free(&ids->patches, 1);
39 return 0;
40 }
41
58 -static struct patch_id *add_commit(struct commit *commit,
59 - struct patch_ids *ids,
60 - int no_add)
42 +static int init_patch_id_entry(struct patch_id *patch,
43 + struct commit *commit,
44 + struct patch_ids *ids)
45 {
62 - struct patch_id_bucket *bucket;
63 - struct patch_id *ent;
64 - unsigned char sha1[20];
65 - int pos;
66 -
67 - if (commit_patch_id(commit, &ids->diffopts, sha1))
68 - return NULL;
69 - pos = patch_pos(ids->table, ids->nr, sha1);
70 - if (0 <= pos)
71 - return ids->table[pos];
72 - if (no_add)
73 - return NULL;
74 -
75 - pos = -1 - pos;
46 + if (commit_patch_id(commit, &ids->diffopts, patch->patch_id))
47 + return -1;
48
77 - bucket = ids->patches;
78 - if (!bucket || (BUCKET_SIZE <= bucket->nr)) {
79 - bucket = xcalloc(1, sizeof(*bucket));
80 - bucket->next = ids->patches;
81 - ids->patches = bucket;
82 - }
83 - ent = &bucket->bucket[bucket->nr++];
84 - hashcpy(ent->patch_id, sha1);
85 -
86 - ALLOC_GROW(ids->table, ids->nr + 1, ids->alloc);
87 - if (pos < ids->nr)
88 - memmove(ids->table + pos + 1, ids->table + pos,
89 - sizeof(ent) * (ids->nr - pos));
90 - ids->nr++;
91 - ids->table[pos] = ent;
92 - return ids->table[pos];
49 + hashmap_entry_init(patch, sha1hash(patch->patch_id));
50 + return 0;
51 }
52
53 struct patch_id *has_commit_patch_id(struct commit *commit,
54 struct patch_ids *ids)
55 {
98 - return add_commit(commit, ids, 1);
56 + struct patch_id patch;
57 +
58 + memset(&patch, 0, sizeof(patch));
59 + if (init_patch_id_entry(&patch, commit, ids))
60 + return NULL;
61 +
62 + return hashmap_get(&ids->patches, &patch, NULL);
63 }
64
65 struct patch_id *add_commit_patch_id(struct commit *commit,
66 struct patch_ids *ids)
67 {
104 - return add_commit(commit, ids, 0);
68 + struct patch_id *key = xcalloc(1, sizeof(*key));
69 +
70 + if (init_patch_id_entry(key, commit, ids)) {
71 + free(key);
72 + return NULL;
73 + }
74 +
75 + hashmap_add(&ids->patches, key);
76 + return key;
77 }
patch-ids.h
+3 -4
@@ -2,15 +2,14 @@
2 #define PATCH_IDS_H
3
4 struct patch_id {
5 - unsigned char patch_id[20];
5 + struct hashmap_entry ent;
6 + unsigned char patch_id[GIT_SHA1_RAWSZ];
7 char seen;
8 };
9
10 struct patch_ids {
11 + struct hashmap patches;
12 struct diff_options diffopts;
11 - int nr, alloc;
12 - struct patch_id **table;
13 - struct patch_id_bucket *patches;
13 };
14
15 int commit_patch_id(struct commit *commit, struct diff_options *options,