/* * 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);}
/*
* 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);
void
main(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 void
bench(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));
}
void
new(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);
}
int
delete(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;
}
void
dump(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;
}
int
count(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;
}
void
stats(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);
}