2 #include "split-index.h"
5 struct split_index
*init_split_index(struct index_state
*istate
)
7 if (!istate
->split_index
) {
8 istate
->split_index
= xcalloc(1, sizeof(*istate
->split_index
));
9 istate
->split_index
->refcount
= 1;
11 return istate
->split_index
;
14 int read_link_extension(struct index_state
*istate
,
15 const void *data_
, unsigned long sz
)
17 const unsigned char *data
= data_
;
18 struct split_index
*si
;
22 return error("corrupt link extension (too short)");
23 si
= init_split_index(istate
);
24 hashcpy(si
->base_sha1
, data
);
29 si
->delete_bitmap
= ewah_new();
30 ret
= ewah_read_mmap(si
->delete_bitmap
, data
, sz
);
32 return error("corrupt delete bitmap in link extension");
35 si
->replace_bitmap
= ewah_new();
36 ret
= ewah_read_mmap(si
->replace_bitmap
, data
, sz
);
38 return error("corrupt replace bitmap in link extension");
40 return error("garbage at the end of link extension");
44 static int write_strbuf(void *user_data
, const void *data
, size_t len
)
46 struct strbuf
*sb
= user_data
;
47 strbuf_add(sb
, data
, len
);
51 int write_link_extension(struct strbuf
*sb
,
52 struct index_state
*istate
)
54 struct split_index
*si
= istate
->split_index
;
55 strbuf_add(sb
, si
->base_sha1
, 20);
56 if (!si
->delete_bitmap
&& !si
->replace_bitmap
)
58 ewah_serialize_to(si
->delete_bitmap
, write_strbuf
, sb
);
59 ewah_serialize_to(si
->replace_bitmap
, write_strbuf
, sb
);
63 static void mark_base_index_entries(struct index_state
*base
)
67 * To keep track of the shared entries between
68 * istate->base->cache[] and istate->cache[], base entry
69 * position is stored in each base entry. All positions start
70 * from 1 instead of 0, which is resrved to say "this is a new
73 for (i
= 0; i
< base
->cache_nr
; i
++)
74 base
->cache
[i
]->index
= i
+ 1;
77 static void mark_entry_for_delete(size_t pos
, void *data
)
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;
87 static void replace_entry(size_t pos
, void *data
)
89 struct index_state
*istate
= data
;
90 struct split_index
*si
= istate
->split_index
;
91 struct cache_entry
*dst
, *src
;
93 if (pos
>= istate
->cache_nr
)
94 die("position for replacement %d exceeds base index size %d",
95 (int)pos
, istate
->cache_nr
);
96 if (si
->nr_replacements
>= si
->saved_cache_nr
)
97 die("too many replacements (%d vs %d)",
98 si
->nr_replacements
, si
->saved_cache_nr
);
99 dst
= istate
->cache
[pos
];
100 if (dst
->ce_flags
& CE_REMOVE
)
101 die("entry %d is marked as both replaced and deleted",
103 src
= si
->saved_cache
[si
->nr_replacements
];
105 die("corrupt link extension, entry %d should have "
106 "zero length name", (int)pos
);
107 src
->index
= pos
+ 1;
108 src
->ce_flags
|= CE_UPDATE_IN_BASE
;
109 src
->ce_namelen
= dst
->ce_namelen
;
110 copy_cache_entry(dst
, src
);
112 si
->nr_replacements
++;
115 void merge_base_index(struct index_state
*istate
)
117 struct split_index
*si
= istate
->split_index
;
120 mark_base_index_entries(si
->base
);
122 si
->saved_cache
= istate
->cache
;
123 si
->saved_cache_nr
= istate
->cache_nr
;
124 istate
->cache_nr
= si
->base
->cache_nr
;
125 istate
->cache
= NULL
;
126 istate
->cache_alloc
= 0;
127 ALLOC_GROW(istate
->cache
, istate
->cache_nr
, istate
->cache_alloc
);
128 memcpy(istate
->cache
, si
->base
->cache
,
129 sizeof(*istate
->cache
) * istate
->cache_nr
);
131 si
->nr_deletions
= 0;
132 si
->nr_replacements
= 0;
133 ewah_each_bit(si
->replace_bitmap
, replace_entry
, istate
);
134 ewah_each_bit(si
->delete_bitmap
, mark_entry_for_delete
, istate
);
135 if (si
->nr_deletions
)
136 remove_marked_cache_entries(istate
);
138 for (i
= si
->nr_replacements
; i
< si
->saved_cache_nr
; i
++) {
139 if (!ce_namelen(si
->saved_cache
[i
]))
140 die("corrupt link extension, entry %d should "
141 "have non-zero length name", i
);
142 add_index_entry(istate
, si
->saved_cache
[i
],
143 ADD_CACHE_OK_TO_ADD
|
144 ADD_CACHE_KEEP_CACHE_TREE
|
146 * we may have to replay what
147 * merge-recursive.c:update_stages()
148 * does, which has this flag on
150 ADD_CACHE_SKIP_DFCHECK
);
151 si
->saved_cache
[i
] = NULL
;
154 ewah_free(si
->delete_bitmap
);
155 ewah_free(si
->replace_bitmap
);
156 free(si
->saved_cache
);
157 si
->delete_bitmap
= NULL
;
158 si
->replace_bitmap
= NULL
;
159 si
->saved_cache
= NULL
;
160 si
->saved_cache_nr
= 0;
163 void prepare_to_write_split_index(struct index_state
*istate
)
165 struct split_index
*si
= init_split_index(istate
);
166 struct cache_entry
**entries
= NULL
, *ce
;
167 int i
, nr_entries
= 0, nr_alloc
= 0;
169 si
->delete_bitmap
= ewah_new();
170 si
->replace_bitmap
= ewah_new();
173 /* Go through istate->cache[] and mark CE_MATCHED to
174 * entry with positive index. We'll go through
175 * base->cache[] later to delete all entries in base
176 * that are not marked eith either CE_MATCHED or
177 * CE_UPDATE_IN_BASE. If istate->cache[i] is a
178 * duplicate, deduplicate it.
180 for (i
= 0; i
< istate
->cache_nr
; i
++) {
181 struct cache_entry
*base
;
182 /* namelen is checked separately */
183 const unsigned int ondisk_flags
=
184 CE_STAGEMASK
| CE_VALID
| CE_EXTENDED_FLAGS
;
185 unsigned int ce_flags
, base_flags
, ret
;
186 ce
= istate
->cache
[i
];
189 if (ce
->index
> si
->base
->cache_nr
) {
193 ce
->ce_flags
|= CE_MATCHED
; /* or "shared" */
194 base
= si
->base
->cache
[ce
->index
- 1];
197 if (ce
->ce_namelen
!= base
->ce_namelen
||
198 strcmp(ce
->name
, base
->name
)) {
202 ce_flags
= ce
->ce_flags
;
203 base_flags
= base
->ce_flags
;
204 /* only on-disk flags matter */
205 ce
->ce_flags
&= ondisk_flags
;
206 base
->ce_flags
&= ondisk_flags
;
207 ret
= memcmp(&ce
->ce_stat_data
, &base
->ce_stat_data
,
208 offsetof(struct cache_entry
, name
) -
209 offsetof(struct cache_entry
, ce_stat_data
));
210 ce
->ce_flags
= ce_flags
;
211 base
->ce_flags
= base_flags
;
213 ce
->ce_flags
|= CE_UPDATE_IN_BASE
;
215 si
->base
->cache
[ce
->index
- 1] = ce
;
217 for (i
= 0; i
< si
->base
->cache_nr
; i
++) {
218 ce
= si
->base
->cache
[i
];
219 if ((ce
->ce_flags
& CE_REMOVE
) ||
220 !(ce
->ce_flags
& CE_MATCHED
))
221 ewah_set(si
->delete_bitmap
, i
);
222 else if (ce
->ce_flags
& CE_UPDATE_IN_BASE
) {
223 ewah_set(si
->replace_bitmap
, i
);
224 ce
->ce_flags
|= CE_STRIP_NAME
;
225 ALLOC_GROW(entries
, nr_entries
+1, nr_alloc
);
226 entries
[nr_entries
++] = ce
;
231 for (i
= 0; i
< istate
->cache_nr
; i
++) {
232 ce
= istate
->cache
[i
];
233 if ((!si
->base
|| !ce
->index
) && !(ce
->ce_flags
& CE_REMOVE
)) {
234 assert(!(ce
->ce_flags
& CE_STRIP_NAME
));
235 ALLOC_GROW(entries
, nr_entries
+1, nr_alloc
);
236 entries
[nr_entries
++] = ce
;
238 ce
->ce_flags
&= ~CE_MATCHED
;
242 * take cache[] out temporarily, put entries[] in its place
245 si
->saved_cache
= istate
->cache
;
246 si
->saved_cache_nr
= istate
->cache_nr
;
247 istate
->cache
= entries
;
248 istate
->cache_nr
= nr_entries
;
251 void finish_writing_split_index(struct index_state
*istate
)
253 struct split_index
*si
= init_split_index(istate
);
255 ewah_free(si
->delete_bitmap
);
256 ewah_free(si
->replace_bitmap
);
257 si
->delete_bitmap
= NULL
;
258 si
->replace_bitmap
= NULL
;
260 istate
->cache
= si
->saved_cache
;
261 istate
->cache_nr
= si
->saved_cache_nr
;
264 void discard_split_index(struct index_state
*istate
)
266 struct split_index
*si
= istate
->split_index
;
269 istate
->split_index
= NULL
;
274 discard_index(si
->base
);
280 void save_or_free_index_entry(struct index_state
*istate
, struct cache_entry
*ce
)
283 istate
->split_index
&&
284 istate
->split_index
->base
&&
285 ce
->index
<= istate
->split_index
->base
->cache_nr
&&
286 ce
== istate
->split_index
->base
->cache
[ce
->index
- 1])
287 ce
->ce_flags
|= CE_REMOVE
;
292 void replace_index_entry_in_base(struct index_state
*istate
,
293 struct cache_entry
*old
,
294 struct cache_entry
*new)
297 istate
->split_index
&&
298 istate
->split_index
->base
&&
299 old
->index
<= istate
->split_index
->base
->cache_nr
) {
300 new->index
= old
->index
;
301 if (old
!= istate
->split_index
->base
->cache
[new->index
- 1])
302 free(istate
->split_index
->base
->cache
[new->index
- 1]);
303 istate
->split_index
->base
->cache
[new->index
- 1] = new;