srcload.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #include "stdinc.h"
  2. #include <bio.h>
  3. #include "dat.h"
  4. #include "fns.h"
  5. #include "error.h"
  6. int num = 100;
  7. int length = 20*1024;
  8. int block= 1024;
  9. int bush = 4;
  10. int iter = 100;
  11. Biobuf *bout;
  12. int maxdepth;
  13. Source *mkroot(Cache*);
  14. void new(Source*, int trace, int);
  15. int delete(Source*);
  16. int count(Source *s, int);
  17. void stats(Source *s);
  18. void dump(Source *s, int ident, ulong entry);
  19. static void bench(Source *r);
  20. void
  21. main(int argc, char *argv[])
  22. {
  23. int i;
  24. Fs *fs;
  25. int csize = 1000;
  26. ulong t;
  27. Source *r;
  28. ARGBEGIN{
  29. case 'i':
  30. iter = atoi(ARGF());
  31. break;
  32. case 'n':
  33. num = atoi(ARGF());
  34. break;
  35. case 'l':
  36. length = atoi(ARGF());
  37. break;
  38. case 'b':
  39. block = atoi(ARGF());
  40. break;
  41. case 'u':
  42. bush = atoi(ARGF());
  43. break;
  44. case 'c':
  45. csize = atoi(ARGF());
  46. break;
  47. }ARGEND;
  48. vtAttach();
  49. bout = vtMemAllocZ(sizeof(Biobuf));
  50. Binit(bout, 1, OWRITE);
  51. fmtinstall('V', vtScoreFmt);
  52. fmtinstall('R', vtErrFmt);
  53. fs = fsOpen(argv[0], nil, csize, OReadWrite);
  54. if(fs == nil)
  55. sysfatal("could not open fs: %r");
  56. t = time(0);
  57. srand(0);
  58. r = fs->source;
  59. dump(r, 0, 0);
  60. fprint(2, "count = %d\n", count(r, 1));
  61. for(i=0; i<num; i++)
  62. new(r, 0, 0);
  63. for(i=0; i<iter; i++){
  64. if(i % 10000 == 0)
  65. stats(r);
  66. new(r, 0, 0);
  67. delete(r);
  68. }
  69. // dump(r, 0, 0);
  70. fprint(2, "count = %d\n", count(r, 1));
  71. // cacheCheck(c);
  72. fprint(2, "deleting\n");
  73. for(i=0; i<num; i++)
  74. delete(r);
  75. // dump(r, 0, 0);
  76. fprint(2, "count = %d\n", count(r, 1));
  77. fprint(2, "total time = %ld\n", time(0)-t);
  78. fsClose(fs);
  79. vtDetach();
  80. exits(0);
  81. }
  82. static void
  83. bench(Source *r)
  84. {
  85. vlong t;
  86. Entry e;
  87. int i;
  88. t = nsec();
  89. for(i=0; i<1000000; i++)
  90. sourceGetEntry(r, &e);
  91. fprint(2, "%f\n", 1e-9*(nsec() - t));
  92. }
  93. void
  94. new(Source *s, int trace, int depth)
  95. {
  96. int i, n;
  97. Source *ss;
  98. Entry e;
  99. if(depth > maxdepth)
  100. maxdepth = depth;
  101. Bflush(bout);
  102. n = sourceGetDirSize(s);
  103. for(i=0; i<n; i++){
  104. ss = sourceOpen(s, nrand(n), OReadWrite);
  105. if(ss == nil || !sourceGetEntry(ss, &e))
  106. continue;
  107. if((e.flags & VtEntryDir) && frand() < 1./bush){
  108. if(trace){
  109. int j;
  110. for(j=0; j<trace; j++)
  111. Bprint(bout, " ");
  112. Bprint(bout, "decend %d\n", i);
  113. }
  114. new(ss, trace?trace+1:0, depth+1);
  115. sourceClose(ss);
  116. return;
  117. }
  118. sourceClose(ss);
  119. }
  120. ss = sourceCreate(s, s->dsize, 1+frand()>.5, 0);
  121. if(ss == nil){
  122. Bprint(bout, "could not create directory: %R\n");
  123. return;
  124. }
  125. if(trace){
  126. int j;
  127. for(j=1; j<trace; j++)
  128. Bprint(bout, " ");
  129. Bprint(bout, "create %d\n", ss->offset);
  130. }
  131. sourceClose(ss);
  132. }
  133. int
  134. delete(Source *s)
  135. {
  136. int i, n;
  137. Source *ss;
  138. n = sourceGetDirSize(s);
  139. /* check if empty */
  140. for(i=0; i<n; i++){
  141. ss = sourceOpen(s, i, OReadWrite);
  142. if(ss != nil){
  143. sourceClose(ss);
  144. break;
  145. }
  146. }
  147. if(i == n)
  148. return 0;
  149. for(;;){
  150. ss = sourceOpen(s, nrand(n), OReadWrite);
  151. if(ss == nil)
  152. continue;
  153. if(s->dir && delete(ss)){
  154. sourceClose(ss);
  155. return 1;
  156. }
  157. if(1)
  158. break;
  159. sourceClose(ss);
  160. }
  161. sourceRemove(ss);
  162. return 1;
  163. }
  164. void
  165. dump(Source *s, int ident, ulong entry)
  166. {
  167. ulong i, n;
  168. Source *ss;
  169. Entry e;
  170. for(i=0; i<ident; i++)
  171. Bprint(bout, " ");
  172. if(!sourceGetEntry(s, &e)){
  173. fprint(2, "sourceGetEntry failed: %r\n");
  174. return;
  175. }
  176. Bprint(bout, "%4lud: gen %4ud depth %d tag=%x score=%V",
  177. entry, e.gen, e.depth, e.tag, e.score);
  178. if(!s->dir){
  179. Bprint(bout, " data size: %llud\n", e.size);
  180. return;
  181. }
  182. n = sourceGetDirSize(s);
  183. Bprint(bout, " dir size: %lud\n", n);
  184. for(i=0; i<n; i++){
  185. ss = sourceOpen(s, i, 1);
  186. if(ss == nil)
  187. continue;
  188. dump(ss, ident+1, i);
  189. sourceClose(ss);
  190. }
  191. return;
  192. }
  193. int
  194. count(Source *s, int rec)
  195. {
  196. ulong i, n;
  197. int c;
  198. Source *ss;
  199. n = sourceGetDirSize(s);
  200. c = 0;
  201. for(i=0; i<n; i++){
  202. ss = sourceOpen(s, i, OReadOnly);
  203. if(ss == nil)
  204. continue;
  205. if(rec)
  206. c += count(ss, rec);
  207. c++;
  208. sourceClose(ss);
  209. }
  210. return c;
  211. }
  212. void
  213. stats(Source *s)
  214. {
  215. int n, i, c, cc, max;
  216. Source *ss;
  217. cc = 0;
  218. max = 0;
  219. n = sourceGetDirSize(s);
  220. for(i=0; i<n; i++){
  221. ss = sourceOpen(s, i, 1);
  222. if(ss == nil)
  223. continue;
  224. cc++;
  225. c = count(ss, 1);
  226. if(c > max)
  227. max = c;
  228. sourceClose(ss);
  229. }
  230. fprint(2, "count = %d top = %d depth=%d maxcount %d\n", cc, n, maxdepth, max);
  231. }