diff options
Diffstat (limited to 'split-index.c')
-rw-r--r-- | split-index.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/split-index.c b/split-index.c new file mode 100644 index 0000000000..63b52bb086 --- /dev/null +++ b/split-index.c @@ -0,0 +1,90 @@ +#include "cache.h" +#include "split-index.h" + +struct split_index *init_split_index(struct index_state *istate) +{ + if (!istate->split_index) { + istate->split_index = xcalloc(1, sizeof(*istate->split_index)); + istate->split_index->refcount = 1; + } + return istate->split_index; +} + +int read_link_extension(struct index_state *istate, + const void *data_, unsigned long sz) +{ + const unsigned char *data = data_; + struct split_index *si; + if (sz < 20) + return error("corrupt link extension (too short)"); + si = init_split_index(istate); + hashcpy(si->base_sha1, data); + data += 20; + sz -= 20; + if (sz) + return error("garbage at the end of link extension"); + return 0; +} + +int write_link_extension(struct strbuf *sb, + struct index_state *istate) +{ + struct split_index *si = istate->split_index; + strbuf_add(sb, si->base_sha1, 20); + return 0; +} + +static void mark_base_index_entries(struct index_state *base) +{ + int i; + /* + * To keep track of the shared entries between + * istate->base->cache[] and istate->cache[], base entry + * position is stored in each base entry. All positions start + * from 1 instead of 0, which is resrved to say "this is a new + * entry". + */ + for (i = 0; i < base->cache_nr; i++) + base->cache[i]->index = i + 1; +} + +void merge_base_index(struct index_state *istate) +{ + struct split_index *si = istate->split_index; + + mark_base_index_entries(si->base); + istate->cache_nr = si->base->cache_nr; + ALLOC_GROW(istate->cache, istate->cache_nr, istate->cache_alloc); + memcpy(istate->cache, si->base->cache, + sizeof(*istate->cache) * istate->cache_nr); +} + +void prepare_to_write_split_index(struct index_state *istate) +{ + struct split_index *si = init_split_index(istate); + /* take cache[] out temporarily */ + si->saved_cache_nr = istate->cache_nr; + istate->cache_nr = 0; +} + +void finish_writing_split_index(struct index_state *istate) +{ + struct split_index *si = init_split_index(istate); + istate->cache_nr = si->saved_cache_nr; +} + +void discard_split_index(struct index_state *istate) +{ + struct split_index *si = istate->split_index; + if (!si) + return; + istate->split_index = NULL; + si->refcount--; + if (si->refcount) + return; + if (si->base) { + discard_index(si->base); + free(si->base); + } + free(si); +} |