ref: 2b5a7cebc2274c5780e2cf62d3e18d0171773231
parent: 637a770a1698da227bcd296bd5578d978bea6e34
author: cinap_lenrek <cinap_lenrek@localhost>
date: Mon Jun 27 05:45:33 EDT 2011
hgfs: add tree caching
--- a/sys/src/cmd/hgfs/dat.h
+++ b/sys/src/cmd/hgfs/dat.h
@@ -66,10 +66,7 @@
struct Revtree
{
Ref;
-
int level;
-
- Revinfo *info;
Revnode *root;
};
--- a/sys/src/cmd/hgfs/fs.c
+++ b/sys/src/cmd/hgfs/fs.c
@@ -53,6 +53,47 @@
return ri;
}
+static Revtree*
+getrevtree(Revtree *(*fn)(Revlog *, Revlog *, Revinfo *), Revinfo *ri)
+{
+ static ulong gen;
+ static struct {
+ ulong g;
+ void *f;
+ Revinfo *i;
+ Revtree *t;
+ } cache[4];
+ Revtree *rt;
+ int i, j;
+
+ for(i=j=0; i<nelem(cache); i++){
+ if(cache[i].t == nil){
+ j = i;
+ continue;
+ }
+ if(cache[i].f == fn && cache[i].i == ri){
+ cache[i].g = ++gen;
+ rt = cache[i].t;
+ goto found;
+ }
+ if(cache[j].t && cache[i].g < cache[j].g)
+ j = i;
+ }
+ if((rt = (*fn)(&changelog, &manifest, ri)) == nil)
+ return nil;
+
+ closerevtree(cache[j].t);
+
+ cache[j].g = ++gen;
+ cache[j].f = fn;
+ cache[j].i = ri;
+ cache[j].t = rt;
+
+found:
+ incref(rt);
+ return rt;
+}
+
static char*
fsmkuid(char *s)
{
@@ -281,6 +322,7 @@
static char*
fswalk1(Fid *fid, char *name, Qid *qid)
{
+ Revtree* (*loadfn)(Revlog *, Revlog *, Revinfo *);
Revfile *rf;
Revnode *nd;
int i;
@@ -329,19 +371,20 @@
if(strcmp(name, nametab[i]) == 0)
break;
}
+ loadfn = nil;
switch(i){
case Qtree:
goto Notfound;
case Qfiles:
- if((rf->tree = loadfilestree(&changelog, &manifest, rf->info)) == nil)
- goto Notfound;
+ loadfn = loadfilestree;
break;
case Qchanges:
- if((rf->tree = loadchangestree(&changelog, &manifest, rf->info)) == nil)
- goto Notfound;
+ loadfn = loadchangestree;
break;
}
- if(rf->tree){
+ if(loadfn){
+ if((rf->tree = getrevtree(loadfn, rf->info)) == nil)
+ goto Notfound;
rf->node = rf->tree->root;
rf->tree->level = i;
}
--- a/sys/src/cmd/hgfs/tree.c
+++ b/sys/src/cmd/hgfs/tree.c
@@ -164,8 +164,6 @@
memset(t, 0, sizeof(*t));
incref(t);
- t->info = ri;
-
t->root = malloc(sizeof(Revnode));
t->root->path = 0;
t->root->name = 0;