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