1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
4 
5 enum
6 {
7 	ClumpChunks	= 32*1024
8 };
9 
10 static int	verbose;
11 
12 int
clumpinfoeq(ClumpInfo * c,ClumpInfo * d)13 clumpinfoeq(ClumpInfo *c, ClumpInfo *d)
14 {
15 	return c->type == d->type
16 		&& c->size == d->size
17 		&& c->uncsize == d->uncsize
18 		&& scorecmp(c->score, d->score)==0;
19 }
20 
21 int
findscore(Arena * arena,uchar * score)22 findscore(Arena *arena, uchar *score)
23 {
24 	IEntry ie;
25 	ClumpInfo *ci, *cis;
26 	u64int a;
27 	u32int clump;
28 	int i, n, found;
29 
30 //ZZZ remove fprint?
31 	if(arena->memstats.clumps)
32 		fprint(2, "reading directory for arena=%s with %d entries\n",
33 			arena->name, arena->memstats.clumps);
34 
35 	cis = MKN(ClumpInfo, ClumpChunks);
36 	found = 0;
37 	a = 0;
38 	memset(&ie, 0, sizeof(IEntry));
39 	for(clump = 0; clump < arena->memstats.clumps; clump += n){
40 		n = ClumpChunks;
41 		if(n > arena->memstats.clumps - clump)
42 			n = arena->memstats.clumps - clump;
43 		if(readclumpinfos(arena, clump, cis, n) != n){
44 			seterr(EOk, "arena directory read failed: %r");
45 			break;
46 		}
47 
48 		for(i = 0; i < n; i++){
49 			ci = &cis[i];
50 			if(scorecmp(score, ci->score)==0){
51 				fprint(2, "found at clump=%d with type=%d size=%d csize=%d position=%lld\n",
52 					clump + i, ci->type, ci->uncsize, ci->size, a);
53 				found++;
54 			}
55 			a += ci->size + ClumpSize;
56 		}
57 	}
58 	free(cis);
59 	return found;
60 }
61 
62 void
usage(void)63 usage(void)
64 {
65 	fprint(2, "usage: findscore [-v] arenafile score\n");
66 	threadexitsall(0);
67 }
68 
69 void
threadmain(int argc,char * argv[])70 threadmain(int argc, char *argv[])
71 {
72 	ArenaPart *ap;
73 	Part *part;
74 	char *file;
75 	u8int score[VtScoreSize];
76 	int i, found;
77 
78 	ventifmtinstall();
79 
80 	ARGBEGIN{
81 	case 'v':
82 		verbose++;
83 		break;
84 	default:
85 		usage();
86 		break;
87 	}ARGEND
88 
89 	readonly = 1;
90 
91 	if(argc != 2)
92 		usage();
93 
94 	file = argv[0];
95 	if(strscore(argv[1], score) < 0)
96 		sysfatal("bad score %s", argv[1]);
97 
98 	part = initpart(file, OREAD|ODIRECT);
99 	if(part == nil)
100 		sysfatal("can't open partition %s: %r", file);
101 
102 	ap = initarenapart(part);
103 	if(ap == nil)
104 		sysfatal("can't initialize arena partition in %s: %r", file);
105 
106 	if(verbose > 1){
107 		printarenapart(2, ap);
108 		fprint(2, "\n");
109 	}
110 
111 	initdcache(8 * MaxDiskBlock);
112 
113 	found = 0;
114 	for(i = 0; i < ap->narenas; i++)
115 		found += findscore(ap->arenas[i], score);
116 
117 	print("found %d occurrences of %V\n", found, score);
118 
119 	if(verbose > 1)
120 		printstats();
121 	threadexitsall(0);
122 }
123