Skip to content

Commit f7c22cc

Browse files
Nicolas PitreJunio C Hamano
authored andcommitted
always start looking up objects in the last used pack first
Jon Smirl said: | Once an object reference hits a pack file it is very likely that | following references will hit the same pack file. So first place to | look for an object is the same place the previous object was found. This is indeed a good heuristic so here it is. The search always start with the pack where the last object lookup succeeded. If the wanted object is not available there then the search continues with the normal pack ordering. To test this I split the Linux repository into 66 packs and performed a "time git-rev-list --objects --all > /dev/null". Best results are as follows: Pack Sort w/o this patch w/ this patch ------------------------------------------------------------- recent objects last 26.4s 20.9s recent objects first 24.9s 18.4s This shows that the pack order based on object age has some influence, but that the last-used-pack heuristic is even more significant in reducing object lookup. Signed-off-by: Nicolas Pitre <nico@cam.org> --- Note: the --max-pack-size to git-repack currently produces packs with old objects after those containing recent objects. The pack sort based on filesystem timestamp is therefore backward for those. This needs to be fixed of course, but at least it made me think about this variable for the test. Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 5c5ba73 commit f7c22cc

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

sha1_file.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,20 +1654,25 @@ static int matches_pack_name(struct packed_git *p, const char *ig)
16541654

16551655
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
16561656
{
1657+
static struct packed_git *last_found = (void *)1;
16571658
struct packed_git *p;
16581659
off_t offset;
16591660

16601661
prepare_packed_git();
1662+
if (!packed_git)
1663+
return 0;
1664+
p = (last_found == (void *)1) ? packed_git : last_found;
16611665

1662-
for (p = packed_git; p; p = p->next) {
1666+
do {
16631667
if (ignore_packed) {
16641668
const char **ig;
16651669
for (ig = ignore_packed; *ig; ig++)
16661670
if (!matches_pack_name(p, *ig))
16671671
break;
16681672
if (*ig)
1669-
continue;
1673+
goto next;
16701674
}
1675+
16711676
offset = find_pack_entry_one(sha1, p);
16721677
if (offset) {
16731678
/*
@@ -1680,14 +1685,23 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, cons
16801685
*/
16811686
if (p->pack_fd == -1 && open_packed_git(p)) {
16821687
error("packfile %s cannot be accessed", p->pack_name);
1683-
continue;
1688+
goto next;
16841689
}
16851690
e->offset = offset;
16861691
e->p = p;
16871692
hashcpy(e->sha1, sha1);
1693+
last_found = p;
16881694
return 1;
16891695
}
1690-
}
1696+
1697+
next:
1698+
if (p == last_found)
1699+
p = packed_git;
1700+
else
1701+
p = p->next;
1702+
if (p == last_found)
1703+
p = p->next;
1704+
} while (p);
16911705
return 0;
16921706
}
16931707

0 commit comments

Comments
 (0)