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