xref: /plan9/sys/src/cmd/fossil/srcload.c (revision 5e96a66c77eb9140492ca53f857cbbf108e128ed)
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