Skip to content

Commit c49b260

Browse files
author
Junio C Hamano
committed
Merge branch 'jc/repack'
* jc/repack: prepare_packed_git(): sort packs by age and localness.
2 parents c1f5086 + b867092 commit c49b260

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ extern struct packed_git {
372372
struct packed_git *next;
373373
struct pack_window *windows;
374374
uint32_t *index_base;
375+
time_t mtime;
375376
off_t index_size;
376377
off_t pack_size;
377378
int pack_fd;

sha1_file.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ struct packed_git *add_packed_git(char *path, int path_len, int local)
739739
p->windows = NULL;
740740
p->pack_fd = -1;
741741
p->pack_local = local;
742+
p->mtime = st.st_mtime;
742743
if ((path_len > 44) && !get_sha1_hex(path + path_len - 44, sha1))
743744
hashcpy(p->sha1, sha1);
744745
return p;
@@ -823,6 +824,60 @@ static void prepare_packed_git_one(char *objdir, int local)
823824
closedir(dir);
824825
}
825826

827+
static int sort_pack(const void *a_, const void *b_)
828+
{
829+
struct packed_git *a = *((struct packed_git **)a_);
830+
struct packed_git *b = *((struct packed_git **)b_);
831+
int st;
832+
833+
/*
834+
* Local packs tend to contain objects specific to our
835+
* variant of the project than remote ones. In addition,
836+
* remote ones could be on a network mounted filesystem.
837+
* Favor local ones for these reasons.
838+
*/
839+
st = a->pack_local - b->pack_local;
840+
if (st)
841+
return -st;
842+
843+
/*
844+
* Younger packs tend to contain more recent objects,
845+
* and more recent objects tend to get accessed more
846+
* often.
847+
*/
848+
if (a->mtime < b->mtime)
849+
return 1;
850+
else if (a->mtime == b->mtime)
851+
return 0;
852+
return -1;
853+
}
854+
855+
static void rearrange_packed_git(void)
856+
{
857+
struct packed_git **ary, *p;
858+
int i, n;
859+
860+
for (n = 0, p = packed_git; p; p = p->next)
861+
n++;
862+
if (n < 2)
863+
return;
864+
865+
/* prepare an array of packed_git for easier sorting */
866+
ary = xcalloc(n, sizeof(struct packed_git *));
867+
for (n = 0, p = packed_git; p; p = p->next)
868+
ary[n++] = p;
869+
870+
qsort(ary, n, sizeof(struct packed_git *), sort_pack);
871+
872+
/* link them back again */
873+
for (i = 0; i < n - 1; i++)
874+
ary[i]->next = ary[i + 1];
875+
ary[n - 1]->next = NULL;
876+
packed_git = ary[0];
877+
878+
free(ary);
879+
}
880+
826881
static int prepare_packed_git_run_once = 0;
827882
void prepare_packed_git(void)
828883
{
@@ -837,6 +892,7 @@ void prepare_packed_git(void)
837892
prepare_packed_git_one(alt->base, 0);
838893
alt->name[-1] = '/';
839894
}
895+
rearrange_packed_git();
840896
prepare_packed_git_run_once = 1;
841897
}
842898

0 commit comments

Comments
 (0)