279 lines · 4.5 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "stdinc.h"#include <bio.h>#include "dat.h"#include "fns.h"#include "error.h" int num = 100;int length = 20*1024;int block= 1024;int bush = 4;int iter = 100;Biobuf *bout;int maxdepth; Source *mkroot(Cache*);void new(Source*, int trace, int);int delete(Source*);int count(Source *s, int);void stats(Source *s);void dump(Source *s, int ident, ulong entry);static void bench(Source *r); voidmain(int argc, char *argv[]){	int i;	Fs *fs;	int csize = 1000;	ulong t;	Source *r; 	ARGBEGIN{	case 'i':		iter = atoi(ARGF());		break;	case 'n':		num = atoi(ARGF());		break;	case 'l':		length = atoi(ARGF());		break;	case 'b':			block = atoi(ARGF());		break;	case 'u':		bush = atoi(ARGF());		break;	case 'c':		csize = atoi(ARGF());		break;	}ARGEND; 	vtAttach(); 	bout = vtMemAllocZ(sizeof(Biobuf));	Binit(bout, 1, OWRITE); 	fmtinstall('V', vtScoreFmt);	fmtinstall('R', vtErrFmt); 	fs = fsOpen(argv[0], nil, csize, OReadWrite);	if(fs == nil)		sysfatal("could not open fs: %r"); 	t = time(0); 	srand(0); 	r = fs->source;	dump(r, 0, 0); 	fprint(2, "count = %d\n", count(r, 1));	for(i=0; i<num; i++)		new(r, 0, 0); 	for(i=0; i<iter; i++){		if(i % 10000 == 0)			stats(r);		new(r, 0, 0);		delete(r);	} //	dump(r, 0, 0); 	fprint(2, "count = %d\n", count(r, 1));//	cacheCheck(c); 	fprint(2, "deleting\n");	for(i=0; i<num; i++)		delete(r);//	dump(r, 0, 0); 	fprint(2, "count = %d\n", count(r, 1));	fprint(2, "total time = %ld\n", time(0)-t);		fsClose(fs);	vtDetach();	exits(0);} static voidbench(Source *r){	vlong t;	Entry e;	int i; 	t = nsec(); 	for(i=0; i<1000000; i++)		sourceGetEntry(r, &e); 	fprint(2, "%f\n", 1e-9*(nsec() - t));} voidnew(Source *s, int trace, int depth){	int i, n;	Source *ss;	Entry e;		if(depth > maxdepth)		maxdepth = depth; 	Bflush(bout); 	n = sourceGetDirSize(s);	for(i=0; i<n; i++){		ss = sourceOpen(s, nrand(n), OReadWrite);		if(ss == nil || !sourceGetEntry(ss, &e))			continue;		if((e.flags & VtEntryDir) && frand() < 1./bush){			if(trace){				int j;				for(j=0; j<trace; j++)					Bprint(bout, " ");				Bprint(bout, "decend %d\n", i);			}			new(ss, trace?trace+1:0, depth+1);			sourceClose(ss);			return;		}		sourceClose(ss);	}	ss = sourceCreate(s, s->dsize, 1+frand()>.5, 0);	if(ss == nil){		Bprint(bout, "could not create directory: %R\n");		return;	}	if(trace){		int j;		for(j=1; j<trace; j++)			Bprint(bout, " ");		Bprint(bout, "create %d\n", ss->offset);	}	sourceClose(ss);} intdelete(Source *s){	int i, n;	Source *ss; 	n = sourceGetDirSize(s);	/* check if empty */	for(i=0; i<n; i++){		ss = sourceOpen(s, i, OReadWrite);		if(ss != nil){			sourceClose(ss);			break;		}	}	if(i == n)		return 0;			for(;;){		ss = sourceOpen(s, nrand(n), OReadWrite);		if(ss == nil)			continue;		if(s->dir && delete(ss)){			sourceClose(ss);			return 1;		}		if(1)			break;		sourceClose(ss);	}  	sourceRemove(ss);	return 1;} voiddump(Source *s, int ident, ulong entry){	ulong i, n;	Source *ss;	Entry e; 	for(i=0; i<ident; i++)		Bprint(bout, " "); 	if(!sourceGetEntry(s, &e)){		fprint(2, "sourceGetEntry failed: %r\n");		return;	} 	Bprint(bout, "%4lud: gen %4ud depth %d tag=%x score=%V",		entry, e.gen, e.depth, e.tag, e.score);	if(!s->dir){		Bprint(bout, " data size: %llud\n", e.size);		return;	}	n = sourceGetDirSize(s);	Bprint(bout, " dir size: %lud\n", n);	for(i=0; i<n; i++){		ss = sourceOpen(s, i, 1);		if(ss == nil)			continue;		dump(ss, ident+1, i);		sourceClose(ss);	}	return;} intcount(Source *s, int rec){	ulong i, n;	int c;	Source *ss; 	n = sourceGetDirSize(s);	c = 0;	for(i=0; i<n; i++){		ss = sourceOpen(s, i, OReadOnly);		if(ss == nil)			continue;		if(rec)			c += count(ss, rec);		c++;		sourceClose(ss);	}	return c;} voidstats(Source *s){	int n, i, c, cc, max;	Source *ss; 	cc = 0;	max = 0;	n = sourceGetDirSize(s);	for(i=0; i<n; i++){		ss = sourceOpen(s, i, 1);		if(ss == nil)			continue;		cc++;		c = count(ss, 1);		if(c > max)			max = c;		sourceClose(ss);	}fprint(2, "count = %d top = %d depth=%d maxcount %d\n", cc, n, maxdepth, max);}