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
main(int argc,char * argv[])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 vtDetach();
98 exits(0);
99 }
100
101 static void
bench(Source * r)102 bench(Source *r)
103 {
104 vlong t;
105 Entry e;
106 int i;
107
108 t = nsec();
109
110 for(i=0; i<1000000; i++)
111 sourceGetEntry(r, &e);
112
113 fprint(2, "%f\n", 1e-9*(nsec() - t));
114 }
115
116 void
new(Source * s,int trace,int depth)117 new(Source *s, int trace, int depth)
118 {
119 int i, n;
120 Source *ss;
121 Entry e;
122
123 if(depth > maxdepth)
124 maxdepth = depth;
125
126 Bflush(bout);
127
128 n = sourceGetDirSize(s);
129 for(i=0; i<n; i++){
130 ss = sourceOpen(s, nrand(n), OReadWrite);
131 if(ss == nil || !sourceGetEntry(ss, &e))
132 continue;
133 if((e.flags & VtEntryDir) && frand() < 1./bush){
134 if(trace){
135 int j;
136 for(j=0; j<trace; j++)
137 Bprint(bout, " ");
138 Bprint(bout, "decend %d\n", i);
139 }
140 new(ss, trace?trace+1:0, depth+1);
141 sourceClose(ss);
142 return;
143 }
144 sourceClose(ss);
145 }
146 ss = sourceCreate(s, s->dsize, 1+frand()>.5, 0);
147 if(ss == nil){
148 Bprint(bout, "could not create directory: %R\n");
149 return;
150 }
151 if(trace){
152 int j;
153 for(j=1; j<trace; j++)
154 Bprint(bout, " ");
155 Bprint(bout, "create %d\n", ss->offset);
156 }
157 sourceClose(ss);
158 }
159
160 int
delete(Source * s)161 delete(Source *s)
162 {
163 int i, n;
164 Source *ss;
165
166 n = sourceGetDirSize(s);
167 /* check if empty */
168 for(i=0; i<n; i++){
169 ss = sourceOpen(s, i, OReadWrite);
170 if(ss != nil){
171 sourceClose(ss);
172 break;
173 }
174 }
175 if(i == n)
176 return 0;
177
178 for(;;){
179 ss = sourceOpen(s, nrand(n), OReadWrite);
180 if(ss == nil)
181 continue;
182 if(s->dir && delete(ss)){
183 sourceClose(ss);
184 return 1;
185 }
186 if(1)
187 break;
188 sourceClose(ss);
189 }
190
191
192 sourceRemove(ss);
193 return 1;
194 }
195
196 void
dump(Source * s,int ident,ulong entry)197 dump(Source *s, int ident, ulong entry)
198 {
199 ulong i, n;
200 Source *ss;
201 Entry e;
202
203 for(i=0; i<ident; i++)
204 Bprint(bout, " ");
205
206 if(!sourceGetEntry(s, &e)){
207 fprint(2, "sourceGetEntry failed: %r\n");
208 return;
209 }
210
211 Bprint(bout, "%4lud: gen %4ud depth %d tag=%x score=%V",
212 entry, e.gen, e.depth, e.tag, e.score);
213 if(!s->dir){
214 Bprint(bout, " data size: %llud\n", e.size);
215 return;
216 }
217 n = sourceGetDirSize(s);
218 Bprint(bout, " dir size: %lud\n", n);
219 for(i=0; i<n; i++){
220 ss = sourceOpen(s, i, 1);
221 if(ss == nil)
222 continue;
223 dump(ss, ident+1, i);
224 sourceClose(ss);
225 }
226 return;
227 }
228
229 int
count(Source * s,int rec)230 count(Source *s, int rec)
231 {
232 ulong i, n;
233 int c;
234 Source *ss;
235
236 n = sourceGetDirSize(s);
237 c = 0;
238 for(i=0; i<n; i++){
239 ss = sourceOpen(s, i, OReadOnly);
240 if(ss == nil)
241 continue;
242 if(rec)
243 c += count(ss, rec);
244 c++;
245 sourceClose(ss);
246 }
247 return c;
248 }
249
250 void
stats(Source * s)251 stats(Source *s)
252 {
253 int n, i, c, cc, max;
254 Source *ss;
255
256 cc = 0;
257 max = 0;
258 n = sourceGetDirSize(s);
259 for(i=0; i<n; i++){
260 ss = sourceOpen(s, i, 1);
261 if(ss == nil)
262 continue;
263 cc++;
264 c = count(ss, 1);
265 if(c > max)
266 max = c;
267 sourceClose(ss);
268 }
269 fprint(2, "count = %d top = %d depth=%d maxcount %d\n", cc, n, maxdepth, max);
270 }
271