diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-06-27 09:45:33 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-06-27 09:45:33 +0000 |
commit | 2b5a7cebc2274c5780e2cf62d3e18d0171773231 (patch) | |
tree | 0b4767555633b1b4f6005b58c93e6bff7b7d13d1 /sys/src/cmd/hgfs | |
parent | 637a770a1698da227bcd296bd5578d978bea6e34 (diff) |
hgfs: add tree caching
Diffstat (limited to 'sys/src/cmd/hgfs')
-rw-r--r-- | sys/src/cmd/hgfs/dat.h | 3 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/fs.c | 53 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/tree.c | 2 |
3 files changed, 48 insertions, 10 deletions
diff --git a/sys/src/cmd/hgfs/dat.h b/sys/src/cmd/hgfs/dat.h index c63065843..111275649 100644 --- a/sys/src/cmd/hgfs/dat.h +++ b/sys/src/cmd/hgfs/dat.h @@ -66,10 +66,7 @@ struct Revinfo struct Revtree { Ref; - int level; - - Revinfo *info; Revnode *root; }; diff --git a/sys/src/cmd/hgfs/fs.c b/sys/src/cmd/hgfs/fs.c index fea6d214b..0c977d2cc 100644 --- a/sys/src/cmd/hgfs/fs.c +++ b/sys/src/cmd/hgfs/fs.c @@ -53,6 +53,47 @@ getrevinfo(int rev) 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 @@ findrev(Revlog *rl, char *name) static char* fswalk1(Fid *fid, char *name, Qid *qid) { + Revtree* (*loadfn)(Revlog *, Revlog *, Revinfo *); Revfile *rf; Revnode *nd; int i; @@ -329,19 +371,20 @@ fswalk1(Fid *fid, char *name, Qid *qid) 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; } diff --git a/sys/src/cmd/hgfs/tree.c b/sys/src/cmd/hgfs/tree.c index 118c9ac5e..cf71b0c4a 100644 --- a/sys/src/cmd/hgfs/tree.c +++ b/sys/src/cmd/hgfs/tree.c @@ -164,8 +164,6 @@ loadtree(Revlog *manifest, Revinfo *ri, Hashstr **ht, int nh) memset(t, 0, sizeof(*t)); incref(t); - t->info = ri; - t->root = malloc(sizeof(Revnode)); t->root->path = 0; t->root->name = 0; |