replace_object: use oidmap

Load the replace objects into an oidmap to allow for easy lookups in constant time. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Apr 11, 2018 at 17:21 UTC f37b9bc00ca3cb9a22c4d5da564eb271ba13c109
1 file changed +16 -60
replace_object.c
+16 -60
@@ -1,54 +1,14 @@
1 #include "cache.h"
2 -#include "sha1-lookup.h"
2 +#include "oidmap.h"
3 #include "refs.h"
4 #include "commit.h"
5
6 -/*
7 - * An array of replacements. The array is kept sorted by the original
8 - * sha1.
9 - */
10 -static struct replace_object {
11 - struct object_id original;
6 +struct replace_object {
7 + struct oidmap_entry original;
8 struct object_id replacement;
13 -} **replace_object;
14 -
15 -static int replace_object_alloc, replace_object_nr;
9 +};
10
17 -static const unsigned char *replace_sha1_access(size_t index, void *table)
18 -{
19 - struct replace_object **replace = table;
20 - return replace[index]->original.hash;
21 -}
22 -
23 -static int replace_object_pos(const unsigned char *sha1)
24 -{
25 - return sha1_pos(sha1, replace_object, replace_object_nr,
26 - replace_sha1_access);
27 -}
28 -
29 -static int register_replace_object(struct replace_object *replace,
30 - int ignore_dups)
31 -{
32 - int pos = replace_object_pos(replace->original.hash);
33 -
34 - if (0 <= pos) {
35 - if (ignore_dups)
36 - free(replace);
37 - else {
38 - free(replace_object[pos]);
39 - replace_object[pos] = replace;
40 - }
41 - return 1;
42 - }
43 - pos = -pos - 1;
44 - ALLOC_GROW(replace_object, replace_object_nr + 1, replace_object_alloc);
45 - replace_object_nr++;
46 - if (pos < replace_object_nr)
47 - MOVE_ARRAY(replace_object + pos + 1, replace_object + pos,
48 - replace_object_nr - pos - 1);
49 - replace_object[pos] = replace;
50 - return 0;
51 -}
11 +static struct oidmap replace_map = OIDMAP_INIT;
12
13 static int register_replace_ref(const char *refname,
14 const struct object_id *oid,
@@ -59,7 +19,7 @@ static int register_replace_ref(const char *refname,
19 const char *hash = slash ? slash + 1 : refname;
20 struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
21
62 - if (get_oid_hex(hash, &repl_obj->original)) {
22 + if (get_oid_hex(hash, &repl_obj->original.oid)) {
23 free(repl_obj);
24 warning("bad replace ref name: %s", refname);
25 return 0;
@@ -69,7 +29,7 @@ static int register_replace_ref(const char *refname,
29 oidcpy(&repl_obj->replacement, oid);
30
31 /* Register new object */
72 - if (register_replace_object(repl_obj, 1))
32 + if (oidmap_put(&replace_map, repl_obj))
33 die("duplicate replace ref: %s", refname);
34
35 return 0;
@@ -84,7 +44,7 @@ static void prepare_replace_object(void)
44
45 for_each_replace_ref(register_replace_ref, NULL);
46 replace_object_prepared = 1;
87 - if (!replace_object_nr)
47 + if (!replace_map.map.tablesize)
48 check_replace_refs = 0;
49 }
50
@@ -100,21 +60,17 @@ static void prepare_replace_object(void)
60 */
61 const struct object_id *do_lookup_replace_object(const struct object_id *oid)
62 {
103 - int pos, depth = MAXREPLACEDEPTH;
63 + int depth = MAXREPLACEDEPTH;
64 const struct object_id *cur = oid;
65
66 prepare_replace_object();
67
68 /* Try to recursively replace the object */
109 - do {
110 - if (--depth < 0)
111 - die("replace depth too high for object %s",
112 - oid_to_hex(oid));
113 -
114 - pos = replace_object_pos(cur->hash);
115 - if (0 <= pos)
116 - cur = &replace_object[pos]->replacement;
117 - } while (0 <= pos);
118 -
119 - return cur;
69 + while (depth-- > 0) {
70 + struct replace_object *repl_obj = oidmap_get(&replace_map, cur);
71 + if (!repl_obj)
72 + return cur;
73 + cur = &repl_obj->replacement;
74 + }
75 + die("replace depth too high for object %s", oid_to_hex(oid));
76 }