aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/venti
diff options
context:
space:
mode:
authorVenkatesh Srinivas <extrudedaluminiu@gmail.com>2009-08-21 15:55:56 -0400
committerVenkatesh Srinivas <extrudedaluminiu@gmail.com>2009-08-21 15:55:56 -0400
commitda0a205ed60d81a85e1c71e0f31571337ba390a5 (patch)
treeceda3aee15492c1b22f3300735bed2a5fceb36e8 /src/cmd/venti
parentc0cc7cc4da05b5e0c20937a2e1097d4ec200b996 (diff)
downloadplan9port-da0a205ed60d81a85e1c71e0f31571337ba390a5.tar.gz
plan9port-da0a205ed60d81a85e1c71e0f31571337ba390a5.tar.bz2
plan9port-da0a205ed60d81a85e1c71e0f31571337ba390a5.zip
venti/copy: synchronize with Plan 9; indent in verbose mode
http://codereview.appspot.com/110062
Diffstat (limited to 'src/cmd/venti')
-rw-r--r--src/cmd/venti/copy.c121
1 files changed, 112 insertions, 9 deletions
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 <venti.h>
#include <libsec.h>
#include <thread.h>
+#include <avl.h>
+#include <bin.h>
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<n; i+=VtScoreSize)
if(memcmp(buf+i, vtzeroscore, VtScoreSize) != 0)
- walk(buf+i, type-1, base);
+ walk(buf+i, type-1, base, depth+1);
break;
}
- if(vtwrite(zdst, score, type, buf, n) < 0){
+ nwrite++;
+ if(vtwrite(zdst, nscore, type, buf, n) < 0){
/* figure out score for better error message */
/* can't use input argument - might have changed contents */
n = vtzerotruncate(type, buf, n);
sha1(buf, n, score, nil);
sysfatal("writing block %V (type %d): %r", score, type);
}
+ if(!rewrite && memcmp(score, nscore, VtScoreSize) != 0)
+ sysfatal("not rewriting: wrote %V got %V", score, nscore);
+
+ if((type !=0 || base !=0) && verbose){
+ n = vtzerotruncate(type, buf, n);
+ sha1(buf, n, score, nil);
+
+ for(i = 0; i < depth; i++)
+ fprint(2, " ");
+ fprint(2, "<- %V\n", score);
+ }
+
+ markvisited(score, type);
free(buf);
}
@@ -112,6 +203,9 @@ threadmain(int argc, char *argv[])
type = -1;
ARGBEGIN{
+ case 'V':
+ chattyventi++;
+ break;
case 'f':
fast = 1;
break;
@@ -120,6 +214,9 @@ threadmain(int argc, char *argv[])
usage();
ignoreerrors = 1;
break;
+ case 'm':
+ scoretree = mkavltree(scoretreecmp);
+ break;
case 'r':
if(ignoreerrors)
usage();
@@ -128,6 +225,9 @@ threadmain(int argc, char *argv[])
case 't':
type = atoi(EARGF(usage()));
break;
+ case 'v':
+ verbose = 1;
+ break;
default:
usage();
break;
@@ -167,10 +267,13 @@ threadmain(int argc, char *argv[])
sysfatal("could not find block %V of any type", score);
}
- walk(score, type, VtDirType);
+ walk(score, type, VtDirType, 0);
if(changes)
print("%s:%V (%d pointers rewritten)\n", prefix, score, changes);
+ if(verbose)
+ print("%d skipped, %d written\n", nskip, nwrite);
+
if(vtsync(zdst) < 0)
sysfatal("could not sync dst server: %r");