diff options
author | Ori Bernstein <ori@eigenstate.org> | 2021-12-05 00:13:54 +0000 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2021-12-05 00:13:54 +0000 |
commit | f0adfb4dedd27d62db8579cbdac07f72f1500cf9 (patch) | |
tree | 0c8dd6d1bfcbc100909973837bc00aa9b1eb2f1a /sys/src | |
parent | 5465c4c01a38cc47e5636be0e83666693efa304e (diff) |
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).
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/cmd/git/pack.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/sys/src/cmd/git/pack.c b/sys/src/cmd/git/pack.c index c86e06b29..ade8591fa 100644 --- a/sys/src/cmd/git/pack.c +++ b/sys/src/cmd/git/pack.c @@ -253,38 +253,51 @@ openpack(Packf *pf) vlong t; int i, best; - if(pf->pack == nil){ - if((pf->pack = Bopen(pf->path, OREAD)) == nil) - return nil; - openpacks++; + if(pf->pack != nil){ + pf->refs++; + return pf->pack; } - 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; 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; best = i; } } - if(best != -1){ - Bterm(packf[best].pack); - packf[best].pack = nil; - openpacks--; + if(best == -1){ + fprint(2, "no available pack slots\n"); + break; } + Bterm(packf[best].pack); + packf[best].pack = nil; + openpacks--; } + openpacks++; pf->opentm = nsec(); pf->refs++; + if((pf->pack = Bopen(pf->path, OREAD)) == nil) + return nil; return pf->pack; } static void closepack(Packf *pf) { - if(--pf->refs == 0 && pf->pack != nil){ - Bterm(pf->pack); - pf->pack = nil; - } + pf->refs--; } static u32int |