pack-redundant: convert linked lists to use struct object_id
[gitweb.git] / split-index.c
index 35da553655bdf7b70519ecf529544796ca8185b5..660c75f31fb970af06af3aad48b4ecc57e8cc136 100644 (file)
@@ -18,12 +18,12 @@ int read_link_extension(struct index_state *istate,
        struct split_index *si;
        int ret;
 
-       if (sz < 20)
+       if (sz < the_hash_algo->rawsz)
                return error("corrupt link extension (too short)");
        si = init_split_index(istate);
-       hashcpy(si->base_sha1, data);
-       data += 20;
-       sz -= 20;
+       hashcpy(si->base_oid.hash, data);
+       data += the_hash_algo->rawsz;
+       sz -= the_hash_algo->rawsz;
        if (!sz)
                return 0;
        si->delete_bitmap = ewah_new();
@@ -45,7 +45,7 @@ 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);
+       strbuf_add(sb, si->base_oid.hash, the_hash_algo->rawsz);
        if (!si->delete_bitmap && !si->replace_bitmap)
                return 0;
        ewah_serialize_strbuf(si->delete_bitmap, sb);
@@ -167,10 +167,9 @@ void merge_base_index(struct index_state *istate)
 
        ewah_free(si->delete_bitmap);
        ewah_free(si->replace_bitmap);
-       free(si->saved_cache);
+       FREE_AND_NULL(si->saved_cache);
        si->delete_bitmap  = NULL;
        si->replace_bitmap = NULL;
-       si->saved_cache    = NULL;
        si->saved_cache_nr = 0;
 }
 
@@ -187,7 +186,7 @@ void prepare_to_write_split_index(struct index_state *istate)
                /* Go through istate->cache[] and mark CE_MATCHED to
                 * entry with positive index. We'll go through
                 * base->cache[] later to delete all entries in base
-                * that are not marked eith either CE_MATCHED or
+                * that are not marked with either CE_MATCHED or
                 * CE_UPDATE_IN_BASE. If istate->cache[i] is a
                 * duplicate, deduplicate it.
                 */
@@ -239,6 +238,8 @@ void prepare_to_write_split_index(struct index_state *istate)
                                ALLOC_GROW(entries, nr_entries+1, nr_alloc);
                                entries[nr_entries++] = ce;
                        }
+                       if (is_null_oid(&ce->oid))
+                               istate->drop_cache_tree = 1;
                }
        }
 
@@ -304,16 +305,38 @@ void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce
 }
 
 void replace_index_entry_in_base(struct index_state *istate,
-                                struct cache_entry *old,
-                                struct cache_entry *new)
+                                struct cache_entry *old_entry,
+                                struct cache_entry *new_entry)
 {
-       if (old->index &&
+       if (old_entry->index &&
            istate->split_index &&
            istate->split_index->base &&
-           old->index <= istate->split_index->base->cache_nr) {
-               new->index = old->index;
-               if (old != istate->split_index->base->cache[new->index - 1])
-                       free(istate->split_index->base->cache[new->index - 1]);
-               istate->split_index->base->cache[new->index - 1] = new;
+           old_entry->index <= istate->split_index->base->cache_nr) {
+               new_entry->index = old_entry->index;
+               if (old_entry != istate->split_index->base->cache[new_entry->index - 1])
+                       free(istate->split_index->base->cache[new_entry->index - 1]);
+               istate->split_index->base->cache[new_entry->index - 1] = new_entry;
+       }
+}
+
+void add_split_index(struct index_state *istate)
+{
+       if (!istate->split_index) {
+               init_split_index(istate);
+               istate->cache_changed |= SPLIT_INDEX_ORDERED;
+       }
+}
+
+void remove_split_index(struct index_state *istate)
+{
+       if (istate->split_index) {
+               /*
+                * can't discard_split_index(&the_index); because that
+                * will destroy split_index->base->cache[], which may
+                * be shared with the_index.cache[]. So yeah we're
+                * leaking a bit here.
+                */
+               istate->split_index = NULL;
+               istate->cache_changed |= SOMETHING_CHANGED;
        }
 }