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 void
25 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);
110 Source *
111 mkroot(Cache *c)
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;
131 void
132 new(Source *s, int trace, int depth)
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);
152 new(ss, trace?trace+1:0, depth+1);
153 sourceFree(ss);
154 return;
156 sourceFree(ss);
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);
167 sourceFree(ss);
170 int
171 delete(Source *s)
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;
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;
198 if(1)
199 break;
200 sourceFree(ss);
204 sourceRemove(ss);
205 return 1;
208 void
209 dumpone(Source *s)
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;
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;
227 Bprint(bout, "\t%lud %d %llud %V\n", i, ss->dir, ss->size, ss->lump->score);
228 sourceFree(ss);
230 return;
234 void
235 dump(Source *s, int ident, ulong entry)
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;
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);
256 return;
259 int
260 count(Source *s, int rec)
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);
279 return c;
282 void
283 stats(Source *s)
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);
301 fprint(2, "count = %d top = %d depth=%d maxcount %d\n", cc, n, maxdepth, max);