From da0a205ed60d81a85e1c71e0f31571337ba390a5 Mon Sep 17 00:00:00 2001 From: Venkatesh Srinivas Date: Fri, 21 Aug 2009 15:55:56 -0400 Subject: venti/copy: synchronize with Plan 9; indent in verbose mode http://codereview.appspot.com/110062 --- src/cmd/venti/copy.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 9 deletions(-) (limited to 'src/cmd') diff --git a/src/cmd/venti/copy.c b/src/cmd/venti/copy.c index 4a05e053..87075e48 100644 --- a/src/cmd/venti/copy.c +++ b/src/cmd/venti/copy.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include enum { @@ -15,25 +17,93 @@ int rewrite; int ignoreerrors; int fast; int verbose; +int nskip; +int nwrite; + VtConn *zsrc, *zdst; +uchar zeroscore[VtScoreSize]; /* all zeros */ + +typedef struct ScoreTree ScoreTree; +struct ScoreTree +{ + Avl avl; + uchar score[VtScoreSize]; + int type; +}; + +Avltree *scoretree; +Bin *scorebin; + +static int +scoretreecmp(Avl *va, Avl *vb) +{ + ScoreTree *a, *b; + int i; + + a = (ScoreTree*)va; + b = (ScoreTree*)vb; + + i = memcmp(a->score, b->score, VtScoreSize); + if(i != 0) + return i; + return a->type - b->type; +} + +static int +havevisited(uchar score[VtScoreSize], int type) +{ + ScoreTree a; + + if(scoretree == nil) + return 0; + memmove(a.score, score, VtScoreSize); + a.type = type; + return lookupavl(scoretree, &a.avl) != nil; +} + +static void +markvisited(uchar score[VtScoreSize], int type) +{ + ScoreTree *a; + Avl *old; + + if(scoretree == nil) + return; + a = binalloc(&scorebin, sizeof *a, 1); + memmove(a->score, score, VtScoreSize); + a->type = type; + insertavl(scoretree, &a->avl, &old); +} void usage(void) { - fprint(2, "usage: copy [-fir] [-t type] srchost dsthost score\n"); + fprint(2, "usage: copy [-fimrVv] [-t type] srchost dsthost score\n"); threadexitsall("usage"); } void -walk(uchar score[VtScoreSize], uint type, int base) +walk(uchar score[VtScoreSize], uint type, int base, int depth) { int i, n; uchar *buf; + uchar nscore[VtScoreSize]; VtEntry e; VtRoot root; - if(memcmp(score, vtzeroscore, VtScoreSize) == 0) + if(verbose){ + for(i = 0; i < depth; i++) + fprint(2, " "); + fprint(2, "-> %d %d %d %V\n", depth, type, base, score); + } + + if(memcmp(score, vtzeroscore, VtScoreSize) == 0 || memcmp(score, zeroscore, VtScoreSize) == 0) + return; + + if(havevisited(score, type)){ + nskip++; return; + } buf = vtmallocz(VtMaxLumpSize); if(fast && vtread(zdst, score, type, buf, VtMaxLumpSize) >= 0){ @@ -59,8 +129,8 @@ walk(uchar score[VtScoreSize], uint type, int base) fprint(2, "warning: could not unpack root in %V %d\n", score, type); break; } - walk(root.score, VtDirType, 0); - walk(root.prev, VtRootType, 0); + walk(root.prev, VtRootType, 0, depth+1); + walk(root.score, VtDirType, 0, depth+1); if(rewrite) vtrootpack(&root, buf); /* walk might have changed score */ break; @@ -73,7 +143,14 @@ walk(uchar score[VtScoreSize], uint type, int base) } if(!(e.flags & VtEntryActive)) continue; - walk(e.score, e.type, e.type&VtTypeBaseMask); + walk(e.score, e.type, e.type&VtTypeBaseMask, depth+1); + /* + * Don't repack unless we're rewriting -- some old + * vac files have psize==0 and dsize==0, and these + * get rewritten by vtentryunpack to have less strange + * block sizes. So vtentryunpack; vtentrypack does not + * guarantee to preserve the exact bytes in buf. + */ if(rewrite) vtentrypack(&e, buf, i); } @@ -85,17 +162,31 @@ walk(uchar score[VtScoreSize], uint type, int base) default: /* pointers */ for(i=0; i