aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/fossil/srcload.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/fossil/srcload.c')
-rw-r--r--src/cmd/fossil/srcload.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/src/cmd/fossil/srcload.c b/src/cmd/fossil/srcload.c
new file mode 100644
index 00000000..8cf63b4f
--- /dev/null
+++ b/src/cmd/fossil/srcload.c
@@ -0,0 +1,270 @@
+#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);
+}