git: improve pack cache heuristics
the pack cache was very stupid: it would close packs as early as possible, which would prevent packs from getting reused effectively. It would also select a bad pack to close. This picks the oldest pack, refcounts correctly, and keeps up to Npackcache open at once (though it will go over if more are in use).
This commit is contained in:
parent
5465c4c01a
commit
f0adfb4ded
1 changed files with 28 additions and 15 deletions
|
@ -253,38 +253,51 @@ openpack(Packf *pf)
|
||||||
vlong t;
|
vlong t;
|
||||||
int i, best;
|
int i, best;
|
||||||
|
|
||||||
if(pf->pack == nil){
|
if(pf->pack != nil){
|
||||||
if((pf->pack = Bopen(pf->path, OREAD)) == nil)
|
pf->refs++;
|
||||||
return nil;
|
return pf->pack;
|
||||||
openpacks++;
|
|
||||||
}
|
}
|
||||||
if(openpacks == Npackcache){
|
/*
|
||||||
t = pf->opentm;
|
* If we've got more packs open
|
||||||
|
* than we want cached, try to
|
||||||
|
* free up the oldest ones.
|
||||||
|
*
|
||||||
|
* If we can't find a slot, this
|
||||||
|
* isn't fatal; we can just use
|
||||||
|
* another fd.
|
||||||
|
*/
|
||||||
|
while(openpacks >= Npackcache){
|
||||||
|
t = (1ull<<62)-1;
|
||||||
best = -1;
|
best = -1;
|
||||||
for(i = 0; i < npackf; i++){
|
for(i = 0; i < npackf; i++){
|
||||||
if(packf[i].opentm < t && packf[i].refs > 0){
|
if(&packf[i] != pf
|
||||||
|
&& packf[i].pack != nil
|
||||||
|
&& packf[i].opentm < t
|
||||||
|
&& packf[i].refs == 0){
|
||||||
t = packf[i].opentm;
|
t = packf[i].opentm;
|
||||||
best = i;
|
best = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(best != -1){
|
if(best == -1){
|
||||||
Bterm(packf[best].pack);
|
fprint(2, "no available pack slots\n");
|
||||||
packf[best].pack = nil;
|
break;
|
||||||
openpacks--;
|
|
||||||
}
|
}
|
||||||
|
Bterm(packf[best].pack);
|
||||||
|
packf[best].pack = nil;
|
||||||
|
openpacks--;
|
||||||
}
|
}
|
||||||
|
openpacks++;
|
||||||
pf->opentm = nsec();
|
pf->opentm = nsec();
|
||||||
pf->refs++;
|
pf->refs++;
|
||||||
|
if((pf->pack = Bopen(pf->path, OREAD)) == nil)
|
||||||
|
return nil;
|
||||||
return pf->pack;
|
return pf->pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
closepack(Packf *pf)
|
closepack(Packf *pf)
|
||||||
{
|
{
|
||||||
if(--pf->refs == 0 && pf->pack != nil){
|
pf->refs--;
|
||||||
Bterm(pf->pack);
|
|
||||||
pf->pack = nil;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32int
|
static u32int
|
||||||
|
|
Loading…
Reference in a new issue