123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /*
- * 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, uint32_t 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)
- {
- int64_t 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, uint32_t entry)
- {
- uint32_t 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)
- {
- uint32_t 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);
- }
|