static vlong findintoc(HConnect *c, Arena *arena, uchar *score) { uchar *blk; int i; vlong off; vlong coff; ClumpInfo ci; blk = vtmalloc(arena->blocksize); off = arena->base + arena->size; coff = 0; for(i=0; i<arena->memstats.clumps; i++){ if(i%arena->clumpmax == 0){ off -= arena->blocksize; if(readpart(arena->part, off, blk, arena->blocksize) != arena->blocksize){ if(c) hprint(&c->hout, "<i>clump info directory at %#llx: %r</i>\n<br>\n", off); break; } } unpackclumpinfo(&ci, blk+(i%arena->clumpmax)*ClumpInfoSize); if(scorecmp(ci.score, score) == 0){ vtfree(blk); return coff; } coff += ClumpSize + ci.size; } vtfree(blk); return -1; }
int readclumpinfo(Arena *arena, int clump, ClumpInfo *ci) { CIBlock *cib, r; cib = getcib(arena, clump, 0, &r); if(cib == nil) return -1; unpackclumpinfo(ci, &cib->data->data[cib->offset]); putcib(arena, cib); return 0; }
static int diskarenatoc(HConnect *c, Arena *arena) { uchar *blk; int i; vlong off; vlong coff; ClumpInfo ci; char base[512]; int cib; snprint(base, sizeof base, "/disk?disk=%s&type=a&arena=%s", arena->part->name, arena->name); blk = vtmalloc(arena->blocksize); off = arena->base + arena->size; hprint(&c->hout, "<h2>table of contents</h2>\n"); hprint(&c->hout, "<pre>\n"); hprint(&c->hout, "%5s %6s %7s %s\n", "type", "size", "uncsize", "score"); coff = 0; cib = hargint(c, "cib", 0); for(i=0; i<arena->memstats.clumps; i++){ if(i%arena->clumpmax == 0){ off -= arena->blocksize; if(readpart(arena->part, off, blk, arena->blocksize) != arena->blocksize){ hprint(&c->hout, "<i>clump info directory at %#llx: %r</i>\n<br>\n", off); i += arena->clumpmax-1; coff = -1; continue; } } unpackclumpinfo(&ci, blk+(i%arena->clumpmax)*ClumpInfoSize); if(i/arena->clumpmax == cib || i%arena->clumpmax == 0){ hprint(&c->hout, "%5d %6d %7d %V", ci.type, ci.size, ci.uncsize, ci.score); if(coff >= 0) hprint(&c->hout, " at <a href=\"%s&clump=%#llx&score=%V\">%#llx</a>", base, coff, ci.score, coff); if(i/arena->clumpmax != cib) hprint(&c->hout, " <font size=-1><a href=\"%s&cib=%d\">more</a></font>", base, i/arena->clumpmax); hprint(&c->hout, "\n"); } if(coff >= 0) coff += ClumpSize + ci.size; } hprint(&c->hout, "</pre>\n"); return 0; }
int readclumpinfos(Arena *arena, int clump, ClumpInfo *cis, int n) { CIBlock *cib, r; int i; /* * because the clump blocks are laid out * in reverse order at the end of the arena, * it can be a few percent faster to read * the clumps backwards, which reads the * disk blocks forwards. */ for(i = n-1; i >= 0; i--){ cib = getcib(arena, clump + i, 0, &r); if(cib == nil){ n = i; continue; } unpackclumpinfo(&cis[i], &cib->data->data[cib->offset]); putcib(arena, cib); } return n; }