1
0
mirror of https://github.com/git/git synced 2024-07-05 00:58:49 +00:00

pack-redundant: consistent sort method

SZEDER reported that test case t5323 has different test result on MacOS.
This is because `cmp_pack_list_reverse` cannot give identical result
when two pack being sorted has the same size of remaining_objects.

Changes to the sorting function will make consistent test result for
t5323.

The new algorithm to find redundant packs is a trade-off to save memory
resources, and the result of it may be different with old one, and may
be not the best result sometimes.  Update t5323 for the new algorithm.

Reported-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jiang Xin 2019-02-02 21:30:17 +08:00 committed by Junio C Hamano
parent 4bc0cc12c1
commit 0e37abd2e8
2 changed files with 25 additions and 17 deletions

View 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;
@ -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);

View File

@ -165,15 +165,15 @@ test_expect_success 'master: no redundant for pack 1, 2, 3' '
# | T A B C D E F G H I J K L M N O P Q R
# ----+--------------------------------------
# P1 | x x x x x x x x
# P2* | ! ! ! ! ! ! !
# P3 | x x x x x x
# P2 | x x x x x x x
# P3* | ! ! ! ! ! !
# P4 | x x x x x
# P5 | x x x x
# ----+--------------------------------------
# ALL | x x x x x x x x x x x x x x x x x x
#
#############################################################################
test_expect_failure 'master: one of pack-2/pack-3 is redundant (failed on Mac)' '
test_expect_success 'master: one of pack-2/pack-3 is redundant' '
create_pack_in "$master_repo" P4 <<-EOF &&
$J
$K
@ -190,7 +190,7 @@ test_expect_failure 'master: one of pack-2/pack-3 is redundant (failed on Mac)'
(
cd "$master_repo" &&
cat >expect <<-EOF &&
P2:$P2
P3:$P3
EOF
git pack-redundant --all >out &&
format_packfiles <out >actual &&
@ -214,7 +214,7 @@ test_expect_failure 'master: one of pack-2/pack-3 is redundant (failed on Mac)'
# ALL | x x x x x x x x x x x x x x x x x x x
#
#############################################################################
test_expect_failure 'master: pack 2, 4, and 6 are redundant (failed on Mac)' '
test_expect_success 'master: pack 2, 4, and 6 are redundant' '
create_pack_in "$master_repo" P6 <<-EOF &&
$N
$O
@ -254,7 +254,7 @@ test_expect_failure 'master: pack 2, 4, and 6 are redundant (failed on Mac)' '
# ALL | x x x x x x x x x x x x x x x x x x x
#
#############################################################################
test_expect_failure 'master: pack-8 (subset of pack-1) is also redundant (failed on Mac)' '
test_expect_success 'master: pack-8 (subset of pack-1) is also redundant' '
create_pack_in "$master_repo" P8 <<-EOF &&
$A
EOF
@ -281,7 +281,7 @@ test_expect_success 'master: clean loose objects' '
)
'
test_expect_failure 'master: remove redundant packs and pass fsck (failed on Mac)' '
test_expect_success 'master: remove redundant packs and pass fsck' '
(
cd "$master_repo" &&
git pack-redundant --all | xargs rm &&
@ -301,7 +301,7 @@ test_expect_success 'setup shared.git' '
)
'
test_expect_failure 'shared: all packs are redundant, but no output without --alt-odb (failed on Mac)' '
test_expect_success 'shared: all packs are redundant, but no output without --alt-odb' '
(
cd "$shared_repo" &&
git pack-redundant --all >out &&
@ -334,7 +334,7 @@ test_expect_failure 'shared: all packs are redundant, but no output without --al
# ALL | x x x x x x x x x x x x x x x x x x x
#
#############################################################################
test_expect_failure 'shared: show redundant packs in stderr for verbose mode (failed on Mac)' '
test_expect_success 'shared: show redundant packs in stderr for verbose mode' '
(
cd "$shared_repo" &&
cat >expect <<-EOF &&