summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2021-12-05 00:13:54 +0000
committerOri Bernstein <ori@eigenstate.org>2021-12-05 00:13:54 +0000
commitf0adfb4dedd27d62db8579cbdac07f72f1500cf9 (patch)
tree0c8dd6d1bfcbc100909973837bc00aa9b1eb2f1a /sys/src
parent5465c4c01a38cc47e5636be0e83666693efa304e (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.c43
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