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