/* * Fill ib with the next bucket in the stream. */ uint32_t buildbucket(Index *ix, IEStream *ies, IBucket *ib, uint maxdata) { IEntry ie1, ie2; uint8_t *b; uint32_t buck; buck = TWID32; ib->n = 0; while(ies->n){ b = peekientry(ies); if(b == nil) return TWID32; /* fprint(2, "b=%p ies->n=%lld ib.n=%d buck=%d score=%V\n", b, ies->n, ib->n, iebuck(ix, b, ib, ies), b); */ if(ib->n == 0) buck = iebuck(ix, b, ib, ies); else{ if(buck != iebuck(ix, b, ib, ies)) break; if(ientrycmp(&ib->data[(ib->n - 1)* IEntrySize], b) == 0){ /* * guess that the larger address is the correct one to use */ unpackientry(&ie1, &ib->data[(ib->n - 1)* IEntrySize]); unpackientry(&ie2, b); seterr(EOk, "duplicate index entry for score=%V type=%d", ie1.score, ie1.ia.type); ib->n--; if(ie1.ia.addr > ie2.ia.addr) memmove(b, &ib->data[ib->n * IEntrySize], IEntrySize); } } if((ib->n+1)*IEntrySize > maxdata){ seterr(EOk, "bucket overflow"); return TWID32; } memmove(&ib->data[ib->n * IEntrySize], b, IEntrySize); ib->n++; ies->n--; ies->pos += IEntrySize; } return buck; }
void dumpisect(ISect *is) { int j; uchar *buf; u32int i; u64int off; IBucket ib; IEntry ie; buf = emalloc(is->blocksize); for(i=0; i<is->blocks; i++){ off = is->blockbase+(u64int)is->blocksize*i; if(readpart(is->part, off, buf, is->blocksize) < 0) fprint(2, "read %s at 0x%llux: %r\n", is->part->name, off); else{ unpackibucket(&ib, buf, is->bucketmagic); for(j=0; j<ib.n; j++){ unpackientry(&ie, &ib.data[j*IEntrySize]); pie(&ie); } } } }