From 7a4ee46d253e291044bba2d0c54b818b67ac013c Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 23 Nov 2003 17:54:58 +0000 Subject: Initial stab at Venti. --- src/cmd/venti/syncindex0.c | 144 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/cmd/venti/syncindex0.c (limited to 'src/cmd/venti/syncindex0.c') diff --git a/src/cmd/venti/syncindex0.c b/src/cmd/venti/syncindex0.c new file mode 100644 index 00000000..95db1208 --- /dev/null +++ b/src/cmd/venti/syncindex0.c @@ -0,0 +1,144 @@ +#include "stdinc.h" +#include "dat.h" +#include "fns.h" + +enum +{ + ClumpChunks = 32*1024 +}; + +/* + * shell sort is plenty good enough + * because we're going to do a bunch of disk i/o's + */ +static void +sortclumpinfo(ClumpInfo *ci, int *s, int n) +{ + int i, j, m, t; + + for(m = (n + 3) / 5; m > 0; m = (m + 1) / 3){ + for(i = n - m; i-- > 0;){ + for(j = i + m; j < n; j += m){ + if(memcmp(ci[s[j - m]].score, ci[s[j]].score, VtScoreSize) <= 0) + break; + t = s[j]; + s[j] = s[j - m]; + s[j - m] = t; + } + } + } +} + +int +syncarenaindex(Index *ix, Arena *arena, u32int clump, u64int a, int fix) +{ + Packet *pack; + IEntry ie; + IAddr ia; + ClumpInfo *ci, *cis; + u32int now; + u64int *addrs; + int i, n, ok, *s; + + now = time(nil); + cis = MKN(ClumpInfo, ClumpChunks); + addrs = MKN(u64int, ClumpChunks); + s = MKN(int, ClumpChunks); + ok = 0; + for(; clump < arena->clumps; clump += n){ + n = ClumpChunks; + if(n > arena->clumps - clump) + n = arena->clumps - clump; + n = readclumpinfos(arena, clump, cis, n); + if(n <= 0){ + fprint(2, "arena directory read failed\n"); + ok = -1; + break; + } + + for(i = 0; i < n; i++){ + addrs[i] = a; + a += cis[i].size + ClumpSize; + s[i] = i; + } + + sortclumpinfo(cis, s, n); + + for(i = 0; i < n; i++){ + ci = &cis[s[i]]; + ia.type = ci->type; + ia.size = ci->uncsize; + ia.addr = addrs[s[i]]; + ia.blocks = (ci->size + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog; + + if(loadientry(ix, ci->score, ci->type, &ie) < 0) + fprint(2, "missing block type=%d score=%V\n", ci->type, ci->score); + else if(iaddrcmp(&ia, &ie.ia) != 0){ + fprint(2, "\nmismatched index entry and clump at %d\n", clump + i); + fprint(2, "\tclump: type=%d size=%d blocks=%d addr=%lld\n", ia.type, ia.size, ia.blocks, ia.addr); + fprint(2, "\tindex: type=%d size=%d block=%d addr=%lld\n", ie.ia.type, ie.ia.size, ie.ia.blocks, ie.ia.addr); + pack = readlump(ie.score, ie.ia.type, ie.ia.size); + packetfree(pack); + if(pack != nil){ + fprint(2, "duplicated lump\n"); + continue; + } + }else + continue; + if(!fix){ + ok = -1; + continue; + } + ie.ia = ia; + scorecp(ie.score, ci->score); + ie.train = 0; + ie.wtime = now; + if(storeientry(ix, &ie) < 0){ + fprint(2, "can't fix index: %r"); + ok = -1; + } + } + + if(0 && clump / 1000 != (clump + n) / 1000) + fprint(2, "."); + } + free(cis); + free(addrs); + free(s); + return ok; +} + +int +syncindex(Index *ix, int fix) +{ + Arena *arena; + u64int a; + u32int clump; + int i, e, e1, ok, ok1; + + ok = 0; + for(i = 0; i < ix->narenas; i++){ + arena = ix->arenas[i]; + clump = arena->clumps; + a = arena->used; + e = syncarena(arena, TWID32, fix, fix); + e1 = e; + if(fix) + e1 &= ~(SyncHeader|SyncCIZero); + if(e1 == SyncHeader) + fprint(2, "arena %s: header is out-of-date\n", arena->name); + if(e1) + ok = -1; + else{ + ok1 = syncarenaindex(ix, arena, clump, a + ix->amap[i].start, fix); + if(fix && ok1==0 && (e & SyncHeader) && wbarena(arena) < 0) + fprint(2, "arena=%s header write failed: %r\n", arena->name); + ok |= ok1; + } + } + if(fix && wbindex(ix) < 0){ + fprint(2, "can't write back index header for %s: %r\n", ix->name); + return -1; + } + return ok; +} -- cgit v1.2.3