Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
	vtDetach();
98
	exits(0);
99
}
100
 
101
static void
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
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
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
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
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
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
}