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