#include "stdinc.h"
#include "dat.h"
#include "fns.h"
enum
{
ClumpChunks = 32*1024
};
static int verbose;
int
clumpinfoeq(ClumpInfo *c, ClumpInfo *d)
{
return c->type == d->type
&& c->size == d->size
&& c->uncsize == d->uncsize
&& scorecmp(c->score, d->score)==0;
}
int
findscore(Arena *arena, uchar *score)
{
IEntry ie;
ClumpInfo *ci, *cis;
u64int a;
u32int clump;
int i, n, found;
//ZZZ remove fprint?
if(arena->memstats.clumps)
fprint(2, "reading directory for arena=%s with %d entries\n",
arena->name, arena->memstats.clumps);
cis = MKN(ClumpInfo, ClumpChunks);
found = 0;
a = 0;
memset(&ie, 0, sizeof(IEntry));
for(clump = 0; clump < arena->memstats.clumps; clump += n){
n = ClumpChunks;
if(n > arena->memstats.clumps - clump)
n = arena->memstats.clumps - clump;
if(readclumpinfos(arena, clump, cis, n) != n){
seterr(EOk, "arena directory read failed: %r");
break;
}
for(i = 0; i < n; i++){
ci = &cis[i];
if(scorecmp(score, ci->score)==0){
fprint(2, "found at clump=%d with type=%d size=%d csize=%d position=%lld\n",
clump + i, ci->type, ci->uncsize, ci->size, a);
found++;
}
a += ci->size + ClumpSize;
}
}
free(cis);
return found;
}
void
usage(void)
{
fprint(2, "usage: findscore [-v] arenafile score\n");
threadexitsall(0);
}
void
threadmain(int argc, char *argv[])
{
ArenaPart *ap;
Part *part;
char *file;
u8int score[VtScoreSize];
int i, found;
ventifmtinstall();
ARGBEGIN{
case 'v':
verbose++;
break;
default:
usage();
break;
}ARGEND
readonly = 1;
if(argc != 2)
usage();
file = argv[0];
if(strscore(argv[1], score) < 0)
sysfatal("bad score %s", argv[1]);
part = initpart(file, OREAD|ODIRECT);
if(part == nil)
sysfatal("can't open partition %s: %r", file);
ap = initarenapart(part);
if(ap == nil)
sysfatal("can't initialize arena partition in %s: %r", file);
if(verbose > 1){
printarenapart(2, ap);
fprint(2, "\n");
}
initdcache(8 * MaxDiskBlock);
found = 0;
for(i = 0; i < ap->narenas; i++)
found += findscore(ap->arenas[i], score);
print("found %d occurrences of %V\n", found, score);
if(verbose > 1)
printstats();
threadexitsall(0);
}
|