Blob
1 #include "stdinc.h"2 #include <bio.h>3 #include "vac.h"4 #include "dat.h"5 #include "fns.h"6 #include "error.h"8 int num = 1000;9 int length = 20*1024;10 int block= 1024;11 int bush = 4;12 int iter = 10000;13 Biobuf *bout;14 int maxdepth;16 Source *mkroot(Cache*);17 void new(Source*, int trace, int);18 int delete(Source*);19 void dump(Source*, int indent, ulong nentry);20 void dumpone(Source *s);21 int count(Source *s, int);22 void stats(Source *s);24 void25 main(int argc, char *argv[])26 {27 int i;28 Cache *c;29 char *host = nil;30 VtSession *z;31 int csize = 10000;32 Source *r;33 ulong t;35 t = time(0);36 fprint(1, "time = %lud\n", t);38 srand(t);40 ARGBEGIN{41 case 'i':42 iter = atoi(ARGF());43 break;44 case 'n':45 num = atoi(ARGF());46 break;47 case 'l':48 length = atoi(ARGF());49 break;50 case 'b':51 block = atoi(ARGF());52 break;53 case 'h':54 host = ARGF();55 break;56 case 'u':57 bush = atoi(ARGF());58 break;59 case 'c':60 csize = atoi(ARGF());61 break;62 }ARGEND;64 vtAttach();66 bout = vtMemAllocZ(sizeof(Biobuf));67 Binit(bout, 1, OWRITE);69 fmtinstall('V', vtScoreFmt);70 fmtinstall('R', vtErrFmt);72 z = vtDial(host);73 if(z == nil)74 vtFatal("could not connect to server: %s", vtGetError());76 if(!vtConnect(z, 0))77 sysfatal("vtConnect: %r");79 c = cacheAlloc(z, block, csize);80 r = mkroot(c);81 for(i=0; i<num; i++)82 new(r, 0, 0);84 for(i=0; i<iter; i++) {85 if(i % 10000 == 0)86 stats(r);87 new(r, 0, 0);88 delete(r);89 }91 fprint(2, "count = %d top = %lud\n", count(r, 0), sourceGetDirSize(r));92 // cacheCheck(c);93 fprint(2, "deleting\n");94 for(i=0; i<num; i++)95 delete(r);97 // dump(r, 0, 0);99 lumpDecRef(r->lump, 0);100 sourceRemove(r);101 cacheCheck(c);103 vtClose(z);104 vtDetach();106 exits(0);107 }110 Source *111 mkroot(Cache *c)112 {113 Lump *u;114 VtEntry *dir;115 Source *r;117 u = cacheAllocLump(c, VtDirType, cacheGetBlockSize(c), 1);118 dir = (VtEntry*)u->data;119 vtPutUint16(dir->psize, cacheGetBlockSize(c));120 vtPutUint16(dir->dsize, cacheGetBlockSize(c));121 dir->flag = VtEntryActive|VtEntryDir;122 memmove(dir->score, vtZeroScore, VtScoreSize);124 r = sourceAlloc(c, u, 0, 0);125 vtUnlock(u->lk);126 if(r == nil)127 sysfatal("could not create root source: %R");128 return r;129 }131 void132 new(Source *s, int trace, int depth)133 {134 int i, n;135 Source *ss;137 if(depth > maxdepth)138 maxdepth = depth;140 n = sourceGetDirSize(s);141 for(i=0; i<n; i++) {142 ss = sourceOpen(s, nrand(n), 0);143 if(ss == nil)144 continue;145 if(ss->dir && frand() < 1./bush) {146 if(trace) {147 int j;148 for(j=0; j<trace; j++)149 Bprint(bout, " ");150 Bprint(bout, "decend %d\n", i);151 }152 new(ss, trace?trace+1:0, depth+1);153 sourceFree(ss);154 return;155 }156 sourceFree(ss);157 }158 ss = sourceCreate(s, s->psize, s->dsize, 1+frand()>.5, 0);159 if(ss == nil)160 fprint(2, "could not create directory: %R\n");161 if(trace) {162 int j;163 for(j=1; j<trace; j++)164 Bprint(bout, " ");165 Bprint(bout, "create %d %V\n", ss->entry, ss->lump->score);166 }167 sourceFree(ss);168 }170 int171 delete(Source *s)172 {173 int i, n;174 Source *ss;176 assert(s->dir);178 n = sourceGetDirSize(s);179 /* check if empty */180 for(i=0; i<n; i++) {181 ss = sourceOpen(s, i, 1);182 if(ss != nil) {183 sourceFree(ss);184 break;185 }186 }187 if(i == n)188 return 0;190 for(;;) {191 ss = sourceOpen(s, nrand(n), 0);192 if(ss == nil)193 continue;194 if(ss->dir && delete(ss)) {195 sourceFree(ss);196 return 1;197 }198 if(1)199 break;200 sourceFree(ss);201 }204 sourceRemove(ss);205 return 1;206 }208 void209 dumpone(Source *s)210 {211 ulong i, n;212 Source *ss;214 Bprint(bout, "gen %4lud depth %d %V", s->gen, s->depth, s->lump->score);215 if(!s->dir) {216 Bprint(bout, " data size: %llud\n", s->size);217 return;218 }219 n = sourceGetDirSize(s);220 Bprint(bout, " dir size: %lud\n", n);221 for(i=0; i<n; i++) {222 ss = sourceOpen(s, i, 1);223 if(ss == nil) {224 fprint(2, "%lud: %R\n", i);225 continue;226 }227 Bprint(bout, "\t%lud %d %llud %V\n", i, ss->dir, ss->size, ss->lump->score);228 sourceFree(ss);229 }230 return;231 }234 void235 dump(Source *s, int ident, ulong entry)236 {237 ulong i, n;238 Source *ss;240 for(i=0; i<ident; i++)241 Bprint(bout, " ");242 Bprint(bout, "%4lud: gen %4lud depth %d", entry, s->gen, s->depth);243 if(!s->dir) {244 Bprint(bout, " data size: %llud\n", s->size);245 return;246 }247 n = sourceGetDirSize(s);248 Bprint(bout, " dir size: %lud\n", n);249 for(i=0; i<n; i++) {250 ss = sourceOpen(s, i, 1);251 if(ss == nil)252 continue;253 dump(ss, ident+1, i);254 sourceFree(ss);255 }256 return;257 }259 int260 count(Source *s, int rec)261 {262 ulong i, n;263 int c;264 Source *ss;266 if(!s->dir)267 return 0;268 n = sourceGetDirSize(s);269 c = 0;270 for(i=0; i<n; i++) {271 ss = sourceOpen(s, i, 1);272 if(ss == nil)273 continue;274 if(rec)275 c += count(ss, rec);276 c++;277 sourceFree(ss);278 }279 return c;280 }282 void283 stats(Source *s)284 {285 int n, i, c, cc, max;286 Source *ss;288 cc = 0;289 max = 0;290 n = sourceGetDirSize(s);291 for(i=0; i<n; i++) {292 ss = sourceOpen(s, i, 1);293 if(ss == nil)294 continue;295 cc++;296 c = count(ss, 1);297 if(c > max)298 max = c;299 sourceFree(ss);300 }301 fprint(2, "count = %d top = %d depth=%d maxcount %d\n", cc, n, maxdepth, max);302 }