1*5e96a66cSDavid du Colombier #include "stdinc.h" 2*5e96a66cSDavid du Colombier #include <bio.h> 3*5e96a66cSDavid du Colombier #include "dat.h" 4*5e96a66cSDavid du Colombier #include "fns.h" 5*5e96a66cSDavid du Colombier #include "error.h" 6*5e96a66cSDavid du Colombier 7*5e96a66cSDavid du Colombier int num = 100; 8*5e96a66cSDavid du Colombier int length = 20*1024; 9*5e96a66cSDavid du Colombier int block= 1024; 10*5e96a66cSDavid du Colombier int bush = 4; 11*5e96a66cSDavid du Colombier int iter = 100; 12*5e96a66cSDavid du Colombier Biobuf *bout; 13*5e96a66cSDavid du Colombier int maxdepth; 14*5e96a66cSDavid du Colombier 15*5e96a66cSDavid du Colombier Source *mkroot(Cache*); 16*5e96a66cSDavid du Colombier void new(Source*, int trace, int); 17*5e96a66cSDavid du Colombier int delete(Source*); 18*5e96a66cSDavid du Colombier int count(Source *s, int); 19*5e96a66cSDavid du Colombier void stats(Source *s); 20*5e96a66cSDavid du Colombier void dump(Source *s, int ident, ulong entry); 21*5e96a66cSDavid du Colombier static void bench(Source *r); 22*5e96a66cSDavid du Colombier 23*5e96a66cSDavid du Colombier void 24*5e96a66cSDavid du Colombier main(int argc, char *argv[]) 25*5e96a66cSDavid du Colombier { 26*5e96a66cSDavid du Colombier int i; 27*5e96a66cSDavid du Colombier Fs *fs; 28*5e96a66cSDavid du Colombier int csize = 1000; 29*5e96a66cSDavid du Colombier ulong t; 30*5e96a66cSDavid du Colombier Source *r; 31*5e96a66cSDavid du Colombier 32*5e96a66cSDavid du Colombier ARGBEGIN{ 33*5e96a66cSDavid du Colombier case 'i': 34*5e96a66cSDavid du Colombier iter = atoi(ARGF()); 35*5e96a66cSDavid du Colombier break; 36*5e96a66cSDavid du Colombier case 'n': 37*5e96a66cSDavid du Colombier num = atoi(ARGF()); 38*5e96a66cSDavid du Colombier break; 39*5e96a66cSDavid du Colombier case 'l': 40*5e96a66cSDavid du Colombier length = atoi(ARGF()); 41*5e96a66cSDavid du Colombier break; 42*5e96a66cSDavid du Colombier case 'b': 43*5e96a66cSDavid du Colombier block = atoi(ARGF()); 44*5e96a66cSDavid du Colombier break; 45*5e96a66cSDavid du Colombier case 'u': 46*5e96a66cSDavid du Colombier bush = atoi(ARGF()); 47*5e96a66cSDavid du Colombier break; 48*5e96a66cSDavid du Colombier case 'c': 49*5e96a66cSDavid du Colombier csize = atoi(ARGF()); 50*5e96a66cSDavid du Colombier break; 51*5e96a66cSDavid du Colombier }ARGEND; 52*5e96a66cSDavid du Colombier 53*5e96a66cSDavid du Colombier vtAttach(); 54*5e96a66cSDavid du Colombier 55*5e96a66cSDavid du Colombier bout = vtMemAllocZ(sizeof(Biobuf)); 56*5e96a66cSDavid du Colombier Binit(bout, 1, OWRITE); 57*5e96a66cSDavid du Colombier 58*5e96a66cSDavid du Colombier fmtinstall('V', vtScoreFmt); 59*5e96a66cSDavid du Colombier fmtinstall('R', vtErrFmt); 60*5e96a66cSDavid du Colombier 61*5e96a66cSDavid du Colombier fs = fsOpen(argv[0], nil, csize, OReadWrite); 62*5e96a66cSDavid du Colombier if(fs == nil) 63*5e96a66cSDavid du Colombier sysfatal("could not open fs: %r"); 64*5e96a66cSDavid du Colombier 65*5e96a66cSDavid du Colombier t = time(0); 66*5e96a66cSDavid du Colombier 67*5e96a66cSDavid du Colombier srand(0); 68*5e96a66cSDavid du Colombier 69*5e96a66cSDavid du Colombier r = fs->source; 70*5e96a66cSDavid du Colombier dump(r, 0, 0); 71*5e96a66cSDavid du Colombier 72*5e96a66cSDavid du Colombier fprint(2, "count = %d\n", count(r, 1)); 73*5e96a66cSDavid du Colombier for(i=0; i<num; i++) 74*5e96a66cSDavid du Colombier new(r, 0, 0); 75*5e96a66cSDavid du Colombier 76*5e96a66cSDavid du Colombier for(i=0; i<iter; i++){ 77*5e96a66cSDavid du Colombier if(i % 10000 == 0) 78*5e96a66cSDavid du Colombier stats(r); 79*5e96a66cSDavid du Colombier new(r, 0, 0); 80*5e96a66cSDavid du Colombier delete(r); 81*5e96a66cSDavid du Colombier } 82*5e96a66cSDavid du Colombier 83*5e96a66cSDavid du Colombier // dump(r, 0, 0); 84*5e96a66cSDavid du Colombier 85*5e96a66cSDavid du Colombier fprint(2, "count = %d\n", count(r, 1)); 86*5e96a66cSDavid du Colombier // cacheCheck(c); 87*5e96a66cSDavid du Colombier 88*5e96a66cSDavid du Colombier fprint(2, "deleting\n"); 89*5e96a66cSDavid du Colombier for(i=0; i<num; i++) 90*5e96a66cSDavid du Colombier delete(r); 91*5e96a66cSDavid du Colombier // dump(r, 0, 0); 92*5e96a66cSDavid du Colombier 93*5e96a66cSDavid du Colombier fprint(2, "count = %d\n", count(r, 1)); 94*5e96a66cSDavid du Colombier fprint(2, "total time = %ld\n", time(0)-t); 95*5e96a66cSDavid du Colombier 96*5e96a66cSDavid du Colombier fsClose(fs); 97*5e96a66cSDavid du Colombier 98*5e96a66cSDavid du Colombier vtDetach(); 99*5e96a66cSDavid du Colombier 100*5e96a66cSDavid du Colombier exits(0); 101*5e96a66cSDavid du Colombier } 102*5e96a66cSDavid du Colombier 103*5e96a66cSDavid du Colombier static void 104*5e96a66cSDavid du Colombier bench(Source *r) 105*5e96a66cSDavid du Colombier { 106*5e96a66cSDavid du Colombier vlong t; 107*5e96a66cSDavid du Colombier Entry e; 108*5e96a66cSDavid du Colombier int i; 109*5e96a66cSDavid du Colombier 110*5e96a66cSDavid du Colombier t = nsec(); 111*5e96a66cSDavid du Colombier 112*5e96a66cSDavid du Colombier for(i=0; i<1000000; i++) 113*5e96a66cSDavid du Colombier sourceGetEntry(r, &e); 114*5e96a66cSDavid du Colombier 115*5e96a66cSDavid du Colombier fprint(2, "%f\n", 1e-9*(nsec() - t)); 116*5e96a66cSDavid du Colombier } 117*5e96a66cSDavid du Colombier 118*5e96a66cSDavid du Colombier void 119*5e96a66cSDavid du Colombier new(Source *s, int trace, int depth) 120*5e96a66cSDavid du Colombier { 121*5e96a66cSDavid du Colombier int i, n; 122*5e96a66cSDavid du Colombier Source *ss; 123*5e96a66cSDavid du Colombier Entry e; 124*5e96a66cSDavid du Colombier 125*5e96a66cSDavid du Colombier if(depth > maxdepth) 126*5e96a66cSDavid du Colombier maxdepth = depth; 127*5e96a66cSDavid du Colombier 128*5e96a66cSDavid du Colombier Bflush(bout); 129*5e96a66cSDavid du Colombier 130*5e96a66cSDavid du Colombier n = sourceGetDirSize(s); 131*5e96a66cSDavid du Colombier for(i=0; i<n; i++){ 132*5e96a66cSDavid du Colombier ss = sourceOpen(s, nrand(n), OReadWrite); 133*5e96a66cSDavid du Colombier if(ss == nil || !sourceGetEntry(ss, &e)) 134*5e96a66cSDavid du Colombier continue; 135*5e96a66cSDavid du Colombier if((e.flags & VtEntryDir) && frand() < 1./bush){ 136*5e96a66cSDavid du Colombier if(trace){ 137*5e96a66cSDavid du Colombier int j; 138*5e96a66cSDavid du Colombier for(j=0; j<trace; j++) 139*5e96a66cSDavid du Colombier Bprint(bout, " "); 140*5e96a66cSDavid du Colombier Bprint(bout, "decend %d\n", i); 141*5e96a66cSDavid du Colombier } 142*5e96a66cSDavid du Colombier new(ss, trace?trace+1:0, depth+1); 143*5e96a66cSDavid du Colombier sourceClose(ss); 144*5e96a66cSDavid du Colombier return; 145*5e96a66cSDavid du Colombier } 146*5e96a66cSDavid du Colombier sourceClose(ss); 147*5e96a66cSDavid du Colombier } 148*5e96a66cSDavid du Colombier ss = sourceCreate(s, s->dsize, 1+frand()>.5, 0); 149*5e96a66cSDavid du Colombier if(ss == nil){ 150*5e96a66cSDavid du Colombier Bprint(bout, "could not create directory: %R\n"); 151*5e96a66cSDavid du Colombier return; 152*5e96a66cSDavid du Colombier } 153*5e96a66cSDavid du Colombier if(trace){ 154*5e96a66cSDavid du Colombier int j; 155*5e96a66cSDavid du Colombier for(j=1; j<trace; j++) 156*5e96a66cSDavid du Colombier Bprint(bout, " "); 157*5e96a66cSDavid du Colombier Bprint(bout, "create %d\n", ss->offset); 158*5e96a66cSDavid du Colombier } 159*5e96a66cSDavid du Colombier sourceClose(ss); 160*5e96a66cSDavid du Colombier } 161*5e96a66cSDavid du Colombier 162*5e96a66cSDavid du Colombier int 163*5e96a66cSDavid du Colombier delete(Source *s) 164*5e96a66cSDavid du Colombier { 165*5e96a66cSDavid du Colombier int i, n; 166*5e96a66cSDavid du Colombier Source *ss; 167*5e96a66cSDavid du Colombier 168*5e96a66cSDavid du Colombier n = sourceGetDirSize(s); 169*5e96a66cSDavid du Colombier /* check if empty */ 170*5e96a66cSDavid du Colombier for(i=0; i<n; i++){ 171*5e96a66cSDavid du Colombier ss = sourceOpen(s, i, OReadWrite); 172*5e96a66cSDavid du Colombier if(ss != nil){ 173*5e96a66cSDavid du Colombier sourceClose(ss); 174*5e96a66cSDavid du Colombier break; 175*5e96a66cSDavid du Colombier } 176*5e96a66cSDavid du Colombier } 177*5e96a66cSDavid du Colombier if(i == n) 178*5e96a66cSDavid du Colombier return 0; 179*5e96a66cSDavid du Colombier 180*5e96a66cSDavid du Colombier for(;;){ 181*5e96a66cSDavid du Colombier ss = sourceOpen(s, nrand(n), OReadWrite); 182*5e96a66cSDavid du Colombier if(ss == nil) 183*5e96a66cSDavid du Colombier continue; 184*5e96a66cSDavid du Colombier if(s->dir && delete(ss)){ 185*5e96a66cSDavid du Colombier sourceClose(ss); 186*5e96a66cSDavid du Colombier return 1; 187*5e96a66cSDavid du Colombier } 188*5e96a66cSDavid du Colombier if(1) 189*5e96a66cSDavid du Colombier break; 190*5e96a66cSDavid du Colombier sourceClose(ss); 191*5e96a66cSDavid du Colombier } 192*5e96a66cSDavid du Colombier 193*5e96a66cSDavid du Colombier 194*5e96a66cSDavid du Colombier sourceRemove(ss); 195*5e96a66cSDavid du Colombier return 1; 196*5e96a66cSDavid du Colombier } 197*5e96a66cSDavid du Colombier 198*5e96a66cSDavid du Colombier void 199*5e96a66cSDavid du Colombier dump(Source *s, int ident, ulong entry) 200*5e96a66cSDavid du Colombier { 201*5e96a66cSDavid du Colombier ulong i, n; 202*5e96a66cSDavid du Colombier Source *ss; 203*5e96a66cSDavid du Colombier Entry e; 204*5e96a66cSDavid du Colombier 205*5e96a66cSDavid du Colombier for(i=0; i<ident; i++) 206*5e96a66cSDavid du Colombier Bprint(bout, " "); 207*5e96a66cSDavid du Colombier 208*5e96a66cSDavid du Colombier if(!sourceGetEntry(s, &e)){ 209*5e96a66cSDavid du Colombier fprint(2, "sourceGetEntry failed: %r\n"); 210*5e96a66cSDavid du Colombier return; 211*5e96a66cSDavid du Colombier } 212*5e96a66cSDavid du Colombier 213*5e96a66cSDavid du Colombier Bprint(bout, "%4lud: gen %4ud depth %d tag=%x score=%V", entry, e.gen, e.depth, e.tag, e.score); 214*5e96a66cSDavid du Colombier if(!s->dir){ 215*5e96a66cSDavid du Colombier Bprint(bout, " data size: %llud\n", e.size); 216*5e96a66cSDavid du Colombier return; 217*5e96a66cSDavid du Colombier } 218*5e96a66cSDavid du Colombier n = sourceGetDirSize(s); 219*5e96a66cSDavid du Colombier Bprint(bout, " dir size: %lud\n", n); 220*5e96a66cSDavid du Colombier for(i=0; i<n; i++){ 221*5e96a66cSDavid du Colombier ss = sourceOpen(s, i, 1); 222*5e96a66cSDavid du Colombier if(ss == nil) 223*5e96a66cSDavid du Colombier continue; 224*5e96a66cSDavid du Colombier dump(ss, ident+1, i); 225*5e96a66cSDavid du Colombier sourceClose(ss); 226*5e96a66cSDavid du Colombier } 227*5e96a66cSDavid du Colombier return; 228*5e96a66cSDavid du Colombier } 229*5e96a66cSDavid du Colombier 230*5e96a66cSDavid du Colombier int 231*5e96a66cSDavid du Colombier count(Source *s, int rec) 232*5e96a66cSDavid du Colombier { 233*5e96a66cSDavid du Colombier ulong i, n; 234*5e96a66cSDavid du Colombier int c; 235*5e96a66cSDavid du Colombier Source *ss; 236*5e96a66cSDavid du Colombier 237*5e96a66cSDavid du Colombier n = sourceGetDirSize(s); 238*5e96a66cSDavid du Colombier c = 0; 239*5e96a66cSDavid du Colombier for(i=0; i<n; i++){ 240*5e96a66cSDavid du Colombier ss = sourceOpen(s, i, OReadOnly); 241*5e96a66cSDavid du Colombier if(ss == nil) 242*5e96a66cSDavid du Colombier continue; 243*5e96a66cSDavid du Colombier if(rec) 244*5e96a66cSDavid du Colombier c += count(ss, rec); 245*5e96a66cSDavid du Colombier c++; 246*5e96a66cSDavid du Colombier sourceClose(ss); 247*5e96a66cSDavid du Colombier } 248*5e96a66cSDavid du Colombier return c; 249*5e96a66cSDavid du Colombier } 250*5e96a66cSDavid du Colombier 251*5e96a66cSDavid du Colombier void 252*5e96a66cSDavid du Colombier stats(Source *s) 253*5e96a66cSDavid du Colombier { 254*5e96a66cSDavid du Colombier int n, i, c, cc, max; 255*5e96a66cSDavid du Colombier Source *ss; 256*5e96a66cSDavid du Colombier 257*5e96a66cSDavid du Colombier cc = 0; 258*5e96a66cSDavid du Colombier max = 0; 259*5e96a66cSDavid du Colombier n = sourceGetDirSize(s); 260*5e96a66cSDavid du Colombier for(i=0; i<n; i++){ 261*5e96a66cSDavid du Colombier ss = sourceOpen(s, i, 1); 262*5e96a66cSDavid du Colombier if(ss == nil) 263*5e96a66cSDavid du Colombier continue; 264*5e96a66cSDavid du Colombier cc++; 265*5e96a66cSDavid du Colombier c = count(ss, 1); 266*5e96a66cSDavid du Colombier if(c > max) 267*5e96a66cSDavid du Colombier max = c; 268*5e96a66cSDavid du Colombier sourceClose(ss); 269*5e96a66cSDavid du Colombier } 270*5e96a66cSDavid du Colombier fprint(2, "count = %d top = %d depth=%d maxcount %d\n", cc, n, maxdepth, max); 271*5e96a66cSDavid du Colombier } 272