Optimized cvsexportcommit: calling 'cvs status' once instead of once per touched file.
[gitweb.git] / pack-redundant.c
index c8f7d9af7b502e12a3d36fc3b3e796e43b4f2bdb..87077e150c1b53a26464089a2cabafafb32e6636 100644 (file)
@@ -17,7 +17,7 @@ static int load_all_packs, verbose, alt_odb;
 
 struct llist_item {
        struct llist_item *next;
-       unsigned char *sha1;
+       const unsigned char *sha1;
 };
 static struct llist {
        struct llist_item *front;
@@ -104,9 +104,9 @@ static struct llist * llist_copy(struct llist *list)
        return ret;
 }
 
-static inline struct llist_item * llist_insert(struct llist *list,
-                                              struct llist_item *after,
-                                              unsigned char *sha1)
+static inline struct llist_item *llist_insert(struct llist *list,
+                                             struct llist_item *after,
+                                              const unsigned char *sha1)
 {
        struct llist_item *new = llist_item_get();
        new->sha1 = sha1;
@@ -128,12 +128,14 @@ static inline struct llist_item * llist_insert(struct llist *list,
        return new;
 }
 
-static inline struct llist_item *llist_insert_back(struct llist *list, unsigned char *sha1)
+static inline struct llist_item *llist_insert_back(struct llist *list,
+                                                  const unsigned char *sha1)
 {
        return llist_insert(list, list->back, sha1);
 }
 
-static inline struct llist_item *llist_insert_sorted_unique(struct llist *list, unsigned char *sha1, struct llist_item *hint)
+static inline struct llist_item *llist_insert_sorted_unique(struct llist *list,
+                       const unsigned char *sha1, struct llist_item *hint)
 {
        struct llist_item *prev = NULL, *l;
 
@@ -245,16 +247,19 @@ static struct pack_list * pack_list_difference(const struct pack_list *A,
 
 static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
 {
-       int p1_off, p2_off;
-       unsigned char *p1_base, *p2_base;
+       unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
+       const unsigned char *p1_base, *p2_base;
        struct llist_item *p1_hint = NULL, *p2_hint = NULL;
 
-       p1_off = p2_off = 256 * 4 + 4;
-       p1_base = (unsigned char *) p1->pack->index_base;
-       p2_base = (unsigned char *) p2->pack->index_base;
+       p1_base = p1->pack->index_data;
+       p2_base = p2->pack->index_data;
+       p1_base += 256 * 4 + ((p1->pack->index_version < 2) ? 4 : 8);
+       p2_base += 256 * 4 + ((p2->pack->index_version < 2) ? 4 : 8);
+       p1_step = (p1->pack->index_version < 2) ? 24 : 20;
+       p2_step = (p2->pack->index_version < 2) ? 24 : 20;
 
-       while (p1_off <= p1->pack->index_size - 3 * 20 &&
-              p2_off <= p2->pack->index_size - 3 * 20)
+       while (p1_off < p1->pack->num_objects * p1_step &&
+              p2_off < p2->pack->num_objects * p2_step)
        {
                int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
                /* cmp ~ p1 - p2 */
@@ -263,14 +268,14 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
                                        p1_base + p1_off, p1_hint);
                        p2_hint = llist_sorted_remove(p2->unique_objects,
                                        p1_base + p1_off, p2_hint);
-                       p1_off+=24;
-                       p2_off+=24;
+                       p1_off += p1_step;
+                       p2_off += p2_step;
                        continue;
                }
                if (cmp < 0) { /* p1 has the object, p2 doesn't */
-                       p1_off+=24;
+                       p1_off += p1_step;
                } else { /* p2 has the object, p1 doesn't */
-                       p2_off+=24;
+                       p2_off += p2_step;
                }
        }
 }
@@ -350,28 +355,31 @@ static int is_superset(struct pack_list *pl, struct llist *list)
 static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
 {
        size_t ret = 0;
-       int p1_off, p2_off;
-       unsigned char *p1_base, *p2_base;
-
-       p1_off = p2_off = 256 * 4 + 4;
-       p1_base = (unsigned char *)p1->index_base;
-       p2_base = (unsigned char *)p2->index_base;
-
-       while (p1_off <= p1->index_size - 3 * 20 &&
-              p2_off <= p2->index_size - 3 * 20)
+       unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
+       const unsigned char *p1_base, *p2_base;
+
+       p1_base = p1->index_data;
+       p2_base = p2->index_data;
+       p1_base += 256 * 4 + ((p1->index_version < 2) ? 4 : 8);
+       p2_base += 256 * 4 + ((p2->index_version < 2) ? 4 : 8);
+       p1_step = (p1->index_version < 2) ? 24 : 20;
+       p2_step = (p2->index_version < 2) ? 24 : 20;
+
+       while (p1_off < p1->num_objects * p1_step &&
+              p2_off < p2->num_objects * p2_step)
        {
                int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
                /* cmp ~ p1 - p2 */
                if (cmp == 0) {
                        ret++;
-                       p1_off+=24;
-                       p2_off+=24;
+                       p1_off += p1_step;
+                       p2_off += p2_step;
                        continue;
                }
                if (cmp < 0) { /* p1 has the object, p2 doesn't */
-                       p1_off+=24;
+                       p1_off += p1_step;
                } else { /* p2 has the object, p1 doesn't */
-                       p2_off+=24;
+                       p2_off += p2_step;
                }
        }
        return ret;
@@ -533,8 +541,8 @@ static void scan_alt_odb_packs(void)
 static struct pack_list * add_pack(struct packed_git *p)
 {
        struct pack_list l;
-       size_t off;
-       unsigned char *base;
+       unsigned long off = 0, step;
+       const unsigned char *base;
 
        if (!p->pack_local && !(alt_odb || verbose))
                return NULL;
@@ -542,11 +550,12 @@ static struct pack_list * add_pack(struct packed_git *p)
        l.pack = p;
        llist_init(&l.all_objects);
 
-       off = 256 * 4 + 4;
-       base = (unsigned char *)p->index_base;
-       while (off <= p->index_size - 3 * 20) {
+       base = p->index_data;
+       base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
+       step = (p->index_version < 2) ? 24 : 20;
+       while (off < p->num_objects * step) {
                llist_insert_back(l.all_objects, base + off);
-               off += 24;
+               off += step;
        }
        /* this list will be pruned in cmp_two_packs later */
        l.unique_objects = llist_copy(l.all_objects);