/* * read in all of the arena's clump directory, * convert to IEntry format, and bucket sort based * on the first few bits. */ static uint32_t readarenainfo(IEBucks *ib, Arena *arena, uint64_t a, Bloom *b) { IEntry ie; ClumpInfo *ci, *cis; uint32_t clump; int i, n, ok, nskip; if(arena->memstats.clumps) fprint(2, "\tarena %s: %d entries\n", arena->name, arena->memstats.clumps); else fprint(2, "[%s] ", arena->name); cis = MKN(ClumpInfo, ClumpChunks); ok = 0; nskip = 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"); ok = -1; break; } for(i = 0; i < n; i++){ ci = &cis[i]; ie.ia.type = ci->type; ie.ia.size = ci->uncsize; ie.ia.addr = a; a += ci->size + ClumpSize; ie.ia.blocks = (ci->size + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog; scorecp(ie.score, ci->score); if(ci->type == VtCorruptType){ if(0) print("! %V %22lld %3d %5d %3d\n", ie.score, ie.ia.addr, ie.ia.type, ie.ia.size, ie.ia.blocks); nskip++; }else sprayientry(ib, &ie); markbloomfilter(b, ie.score); } } free(cis); if(ok < 0) return TWID32; return clump - nskip; }
/* * load clump info group information by scanning entire toc. */ static void loadcig(Arena *arena) { uint32_t i, j, ncig, nci; ArenaCIG *cig; ClumpInfo *ci; uint64_t offset; int ms; if(arena->cig || arena->ncig < 0) return; // fprint(2, "loadcig %s\n", arena->name); ncig = (arena->memstats.clumps+ArenaCIGSize-1) / ArenaCIGSize; if(ncig == 0){ arena->cig = vtmalloc(1); arena->ncig = 0; return; } ms = msec(); cig = vtmalloc(ncig*sizeof cig[0]); ci = vtmalloc(ArenaCIGSize*sizeof ci[0]); offset = 0; for(i=0; i<ncig; i++){ nci = readclumpinfos(arena, i*ArenaCIGSize, ci, ArenaCIGSize); cig[i].offset = offset; for(j=0; j<nci; j++) offset += ClumpSize + ci[j].size; if(nci < ArenaCIGSize){ if(i != ncig-1){ vtfree(ci); vtfree(cig); arena->ncig = -1; fprint(2, "loadcig %s: got %ud cigs, expected %ud\n", arena->name, i+1, ncig); goto out; } } } vtfree(ci); arena->ncig = ncig; arena->cig = cig; out: ms = msec() - ms; addstat2(StatCigLoad, 1, StatCigLoadTime, ms); }
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; }
static int readarenainfo(Arena *arena) { ClumpInfo *ci, *cis; uint32_t clump; int i, n, ok; if(arena->memstats.clumps) fprint(2, "reading directory for arena=%s with %d entries\n", arena->name, arena->memstats.clumps); cis = MKN(ClumpInfo, ClumpChunks); ok = 0; for(clump = 0; clump < arena->memstats.clumps; clump += n){ n = ClumpChunks; if(n > arena->memstats.clumps - clump) n = arena->memstats.clumps - clump; if((i=readclumpinfos(arena, clump, cis, n)) != n){ seterr(EOk, "arena directory read failed %d not %d: %r", i, n); ok = -1; break; } for(i = 0; i < n; i++){ ci = &cis[i]; if(ci->type >= VtMaxType || ci->uncsize >= VtMaxLumpSize) { fprint(2, "bad clump: %d: type = %d: size = %d\n", clump+i, ci->type, ci->uncsize); continue; } count[ci->uncsize][ci->type]++; } } free(cis); if(ok < 0) return TWID32; return clump; }