split-index.con commit read-cache: split-index mode (5fc2fc8)
   1#include "cache.h"
   2#include "split-index.h"
   3
   4struct split_index *init_split_index(struct index_state *istate)
   5{
   6        if (!istate->split_index) {
   7                istate->split_index = xcalloc(1, sizeof(*istate->split_index));
   8                istate->split_index->refcount = 1;
   9        }
  10        return istate->split_index;
  11}
  12
  13int read_link_extension(struct index_state *istate,
  14                         const void *data_, unsigned long sz)
  15{
  16        const unsigned char *data = data_;
  17        struct split_index *si;
  18        if (sz < 20)
  19                return error("corrupt link extension (too short)");
  20        si = init_split_index(istate);
  21        hashcpy(si->base_sha1, data);
  22        data += 20;
  23        sz -= 20;
  24        if (sz)
  25                return error("garbage at the end of link extension");
  26        return 0;
  27}
  28
  29int write_link_extension(struct strbuf *sb,
  30                         struct index_state *istate)
  31{
  32        struct split_index *si = istate->split_index;
  33        strbuf_add(sb, si->base_sha1, 20);
  34        return 0;
  35}
  36
  37static void mark_base_index_entries(struct index_state *base)
  38{
  39        int i;
  40        /*
  41         * To keep track of the shared entries between
  42         * istate->base->cache[] and istate->cache[], base entry
  43         * position is stored in each base entry. All positions start
  44         * from 1 instead of 0, which is resrved to say "this is a new
  45         * entry".
  46         */
  47        for (i = 0; i < base->cache_nr; i++)
  48                base->cache[i]->index = i + 1;
  49}
  50
  51void merge_base_index(struct index_state *istate)
  52{
  53        struct split_index *si = istate->split_index;
  54
  55        mark_base_index_entries(si->base);
  56        istate->cache_nr = si->base->cache_nr;
  57        ALLOC_GROW(istate->cache, istate->cache_nr, istate->cache_alloc);
  58        memcpy(istate->cache, si->base->cache,
  59               sizeof(*istate->cache) * istate->cache_nr);
  60}
  61
  62void prepare_to_write_split_index(struct index_state *istate)
  63{
  64        struct split_index *si = init_split_index(istate);
  65        /* take cache[] out temporarily */
  66        si->saved_cache_nr = istate->cache_nr;
  67        istate->cache_nr = 0;
  68}
  69
  70void finish_writing_split_index(struct index_state *istate)
  71{
  72        struct split_index *si = init_split_index(istate);
  73        istate->cache_nr = si->saved_cache_nr;
  74}
  75
  76void discard_split_index(struct index_state *istate)
  77{
  78        struct split_index *si = istate->split_index;
  79        if (!si)
  80                return;
  81        istate->split_index = NULL;
  82        si->refcount--;
  83        if (si->refcount)
  84                return;
  85        if (si->base) {
  86                discard_index(si->base);
  87                free(si->base);
  88        }
  89        free(si);
  90}