Merge branch 'jt/t5551-protocol-v2-does-not-have-half-auth'
[gitweb.git] / builtin / pack-redundant.c
index 15cdf233c4e812c1ed803754f9bd063f6329b92a..68c1e547c244e09f6447c361b9c665efbb27192d 100644 (file)
@@ -33,6 +33,7 @@ static struct pack_list {
        struct packed_git *pack;
        struct llist *unique_objects;
        struct llist *remaining_objects;
+       size_t all_objects_size;
 } *local_packs = NULL, *altodb_packs = NULL;
 
 static struct llist_item *free_nodes;
@@ -152,7 +153,7 @@ static inline struct llist_item * llist_sorted_remove(struct llist *list, const
        l = (hint == NULL) ? list->front : hint;
        prev = NULL;
        while (l) {
-               int cmp = oidcmp(l->oid, oid);
+               const int cmp = oidcmp(l->oid, oid);
                if (cmp > 0) /* not in list, since sorted */
                        return prev;
                if (!cmp) { /* found */
@@ -255,7 +256,7 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
        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);
+               const int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
                /* cmp ~ p1 - p2 */
                if (cmp == 0) {
                        p1_hint = llist_sorted_remove(p1->unique_objects,
@@ -340,19 +341,25 @@ static inline off_t pack_set_bytecount(struct pack_list *pl)
        return ret;
 }
 
-static int cmp_pack_list_reverse(const void *a, const void *b)
+static int cmp_remaining_objects(const void *a, const void *b)
 {
        struct pack_list *pl_a = *((struct pack_list **)a);
        struct pack_list *pl_b = *((struct pack_list **)b);
-       size_t sz_a = pl_a->remaining_objects->size;
-       size_t sz_b = pl_b->remaining_objects->size;
 
-       if (sz_a == sz_b)
-               return 0;
-       else if (sz_a < sz_b)
+       if (pl_a->remaining_objects->size == pl_b->remaining_objects->size) {
+               /* have the same remaining_objects, big pack first */
+               if (pl_a->all_objects_size == pl_b->all_objects_size)
+                       return 0;
+               else if (pl_a->all_objects_size < pl_b->all_objects_size)
+                       return 1;
+               else
+                       return -1;
+       } else if (pl_a->remaining_objects->size < pl_b->remaining_objects->size) {
+               /* sort by remaining objects, more objects first */
                return 1;
-       else
+       } else {
                return -1;
+       }
 }
 
 /* Sort pack_list, greater size of remaining_objects first */
@@ -370,7 +377,7 @@ static void sort_pack_list(struct pack_list **pl)
        for (n = 0, p = *pl; p; p = p->next)
                ary[n++] = p;
 
-       QSORT(ary, n, cmp_pack_list_reverse);
+       QSORT(ary, n, cmp_remaining_objects);
 
        /* link them back again */
        for (i = 0; i < n - 1; i++)
@@ -511,6 +518,7 @@ static struct pack_list * add_pack(struct packed_git *p)
                llist_insert_back(l.remaining_objects, (const struct object_id *)(base + off));
                off += step;
        }
+       l.all_objects_size = l.remaining_objects->size;
        l.unique_objects = NULL;
        if (p->pack_local)
                return pack_list_insert(&local_packs, &l);