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,