split-index: the reading part

CE_REMOVE'd entries are removed here because only parts of the code base (unpack_trees in fact) test this bit when they look for the presence of an entry. Leaving them may confuse the code ignores this bit and expects to see a real entry. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Jun 13, 2014 at 19:19 UTC 76b07b37a3fff15ce4852bd070a610b651c42e77
3 files changed +84 -4
read-cache.c
-2
@@ -1569,8 +1569,6 @@ int read_index_from(struct index_state *istate, const char *path)
1569
1570 if (is_null_sha1(split_index->base_sha1))
1571 return ret;
1572 - if (istate->cache_nr)
1573 - die("index in split-index mode must contain no entries");
1572
1573 if (split_index->base)
1574 discard_index(split_index->base);
split-index.c
+82 -2
@@ -16,13 +16,27 @@ int read_link_extension(struct index_state *istate,
16 {
17 const unsigned char *data = data_;
18 struct split_index *si;
19 + int ret;
20 +
21 if (sz < 20)
22 return error("corrupt link extension (too short)");
23 si = init_split_index(istate);
24 hashcpy(si->base_sha1, data);
25 data += 20;
26 sz -= 20;
25 - if (sz)
27 + if (!sz)
28 + return 0;
29 + si->delete_bitmap = ewah_new();
30 + ret = ewah_read_mmap(si->delete_bitmap, data, sz);
31 + if (ret < 0)
32 + return error("corrupt delete bitmap in link extension");
33 + data += ret;
34 + sz -= ret;
35 + si->replace_bitmap = ewah_new();
36 + ret = ewah_read_mmap(si->replace_bitmap, data, sz);
37 + if (ret < 0)
38 + return error("corrupt replace bitmap in link extension");
39 + if (ret != sz)
40 return error("garbage at the end of link extension");
41 return 0;
42 }
@@ -60,15 +74,81 @@ static void mark_base_index_entries(struct index_state *base)
74 base->cache[i]->index = i + 1;
75 }
76
77 +static void mark_entry_for_delete(size_t pos, void *data)
78 +{
79 + struct index_state *istate = data;
80 + if (pos >= istate->cache_nr)
81 + die("position for delete %d exceeds base index size %d",
82 + (int)pos, istate->cache_nr);
83 + istate->cache[pos]->ce_flags |= CE_REMOVE;
84 + istate->split_index->nr_deletions = 1;
85 +}
86 +
87 +static void replace_entry(size_t pos, void *data)
88 +{
89 + struct index_state *istate = data;
90 + struct split_index *si = istate->split_index;
91 + struct cache_entry *dst, *src;
92 + if (pos >= istate->cache_nr)
93 + die("position for replacement %d exceeds base index size %d",
94 + (int)pos, istate->cache_nr);
95 + if (si->nr_replacements >= si->saved_cache_nr)
96 + die("too many replacements (%d vs %d)",
97 + si->nr_replacements, si->saved_cache_nr);
98 + dst = istate->cache[pos];
99 + if (dst->ce_flags & CE_REMOVE)
100 + die("entry %d is marked as both replaced and deleted",
101 + (int)pos);
102 + src = si->saved_cache[si->nr_replacements];
103 + src->index = pos + 1;
104 + src->ce_flags |= CE_UPDATE_IN_BASE;
105 + free(dst);
106 + dst = src;
107 + si->nr_replacements++;
108 +}
109 +
110 void merge_base_index(struct index_state *istate)
111 {
112 struct split_index *si = istate->split_index;
113 + unsigned int i;
114
115 mark_base_index_entries(si->base);
68 - istate->cache_nr = si->base->cache_nr;
116 +
117 + si->saved_cache = istate->cache;
118 + si->saved_cache_nr = istate->cache_nr;
119 + istate->cache_nr = si->base->cache_nr;
120 + istate->cache = NULL;
121 + istate->cache_alloc = 0;
122 ALLOC_GROW(istate->cache, istate->cache_nr, istate->cache_alloc);
123 memcpy(istate->cache, si->base->cache,
124 sizeof(*istate->cache) * istate->cache_nr);
125 +
126 + si->nr_deletions = 0;
127 + si->nr_replacements = 0;
128 + ewah_each_bit(si->replace_bitmap, replace_entry, istate);
129 + ewah_each_bit(si->delete_bitmap, mark_entry_for_delete, istate);
130 + if (si->nr_deletions)
131 + remove_marked_cache_entries(istate);
132 +
133 + for (i = si->nr_replacements; i < si->saved_cache_nr; i++) {
134 + add_index_entry(istate, si->saved_cache[i],
135 + ADD_CACHE_OK_TO_ADD |
136 + /*
137 + * we may have to replay what
138 + * merge-recursive.c:update_stages()
139 + * does, which has this flag on
140 + */
141 + ADD_CACHE_SKIP_DFCHECK);
142 + si->saved_cache[i] = NULL;
143 + }
144 +
145 + ewah_free(si->delete_bitmap);
146 + ewah_free(si->replace_bitmap);
147 + free(si->saved_cache);
148 + si->delete_bitmap = NULL;
149 + si->replace_bitmap = NULL;
150 + si->saved_cache = NULL;
151 + si->saved_cache_nr = 0;
152 }
153
154 void prepare_to_write_split_index(struct index_state *istate)
split-index.h
+2
@@ -12,6 +12,8 @@ struct split_index {
12 struct ewah_bitmap *replace_bitmap;
13 struct cache_entry **saved_cache;
14 unsigned int saved_cache_nr;
15 + unsigned int nr_deletions;
16 + unsigned int nr_replacements;
17 int refcount;
18 };
19