summaryrefslogtreecommitdiff
path: root/sys/src/cmd/hgfs/fs.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-11-21 19:22:46 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2012-11-21 19:22:46 +0100
commit40d11cea3fac49a660b5714b18393c2e74487d54 (patch)
tree09ae5180eaeefffa293cec6d2e71765e0e951f9b /sys/src/cmd/hgfs/fs.c
parent73744b9f4896c513d4d7c40ef4ce1d24703810e9 (diff)
hgfs: various improvements
lazily close revlog files and keep up to 8 revlogs arround. also cache the latest extracted file descriptor of a revision in the revlog. this avoids the quite expensive reextracting/patching when we reopen the same file revision. dont use the racy mktemp()/create, instead create a uniqueue name and create with OEXCL. this also avoids a bunch of access() calls. fix eof case and use pread() in fcopy() to avoid the seeks. dont modify changelog temp file but simulate trailing newline instead.
Diffstat (limited to 'sys/src/cmd/hgfs/fs.c')
-rw-r--r--sys/src/cmd/hgfs/fs.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/sys/src/cmd/hgfs/fs.c b/sys/src/cmd/hgfs/fs.c
index 9c61233c3..727cf64d3 100644
--- a/sys/src/cmd/hgfs/fs.c
+++ b/sys/src/cmd/hgfs/fs.c
@@ -43,6 +43,7 @@ static char *nametab[] = {
static Revlog changelog;
static Revlog manifest;
static Revlog *revlogs;
+static int nfreerevlogs = 0;
static char workdir[MAXPATH];
static int mangle = 0;
@@ -51,16 +52,28 @@ static Revlog*
getrevlog(Revnode *nd)
{
char buf[MAXPATH];
- Revlog *rl;
+ Revlog *rl, **link;
int mang;
mang = mangle;
Again:
nodepath(seprint(buf, buf+sizeof(buf), "%s/.hg/store/data", workdir),
buf+sizeof(buf), nd, mang);
- for(rl = revlogs; rl; rl = rl->next)
- if(strcmp(buf, rl->path) == 0)
+ link = &revlogs;
+ while(rl = *link){
+ if(strcmp(buf, rl->path) == 0){
+ if(rl->ref == 0) nfreerevlogs--;
break;
+ }
+ if(nfreerevlogs > 8 && rl->ref == 0){
+ *link = rl->next;
+ nfreerevlogs--;
+ revlogclose(rl);
+ free(rl);
+ continue;
+ }
+ link = &rl->next;
+ }
if(rl == nil){
rl = emalloc9p(sizeof(*rl));
memset(rl, 0, sizeof(*rl));
@@ -83,18 +96,8 @@ Again:
static void
closerevlog(Revlog *rl)
{
- Revlog **pp;
-
- if(rl == nil || decref(rl))
- return;
- for(pp = &revlogs; *pp; pp = &((*pp)->next)){
- if(*pp == rl){
- *pp = rl->next;
- break;
- }
- }
- revlogclose(rl);
- free(rl);
+ if(rl != nil && decref(rl) == 0)
+ nfreerevlogs++;
}
static Revinfo*