Blob


1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
5 enum
6 {
7 ClumpChunks = 32*1024
8 };
10 /*
11 * shell sort is plenty good enough
12 * because we're going to do a bunch of disk i/o's
13 */
14 static void
15 sortclumpinfo(ClumpInfo *ci, int *s, int n)
16 {
17 int i, j, m, t;
19 for(m = (n + 3) / 5; m > 0; m = (m + 1) / 3){
20 for(i = n - m; i-- > 0;){
21 for(j = i + m; j < n; j += m){
22 if(memcmp(ci[s[j - m]].score, ci[s[j]].score, VtScoreSize) <= 0)
23 break;
24 t = s[j];
25 s[j] = s[j - m];
26 s[j - m] = t;
27 }
28 }
29 }
30 }
32 int
33 syncarenaindex(Index *ix, Arena *arena, u32int clump, u64int a, int fix)
34 {
35 Packet *pack;
36 IEntry ie;
37 IAddr ia;
38 ClumpInfo *ci, *cis;
39 u32int now;
40 u64int *addrs;
41 int i, n, ok, *s;
43 now = time(nil);
44 cis = MKN(ClumpInfo, ClumpChunks);
45 addrs = MKN(u64int, ClumpChunks);
46 s = MKN(int, ClumpChunks);
47 ok = 0;
48 for(; clump < arena->clumps; clump += n){
49 n = ClumpChunks;
50 if(n > arena->clumps - clump)
51 n = arena->clumps - clump;
52 n = readclumpinfos(arena, clump, cis, n);
53 if(n <= 0){
54 fprint(2, "arena directory read failed\n");
55 ok = -1;
56 break;
57 }
59 for(i = 0; i < n; i++){
60 addrs[i] = a;
61 a += cis[i].size + ClumpSize;
62 s[i] = i;
63 }
65 sortclumpinfo(cis, s, n);
67 for(i = 0; i < n; i++){
68 ci = &cis[s[i]];
69 ia.type = ci->type;
70 ia.size = ci->uncsize;
71 ia.addr = addrs[s[i]];
72 ia.blocks = (ci->size + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog;
74 if(loadientry(ix, ci->score, ci->type, &ie) < 0)
75 fprint(2, "missing block type=%d score=%V\n", ci->type, ci->score);
76 else if(iaddrcmp(&ia, &ie.ia) != 0){
77 fprint(2, "\nmismatched index entry and clump at %d\n", clump + i);
78 fprint(2, "\tclump: type=%d size=%d blocks=%d addr=%lld\n", ia.type, ia.size, ia.blocks, ia.addr);
79 fprint(2, "\tindex: type=%d size=%d block=%d addr=%lld\n", ie.ia.type, ie.ia.size, ie.ia.blocks, ie.ia.addr);
80 pack = readlump(ie.score, ie.ia.type, ie.ia.size);
81 packetfree(pack);
82 if(pack != nil){
83 fprint(2, "duplicated lump\n");
84 continue;
85 }
86 }else
87 continue;
88 if(!fix){
89 ok = -1;
90 continue;
91 }
92 ie.ia = ia;
93 scorecp(ie.score, ci->score);
94 ie.train = 0;
95 ie.wtime = now;
96 if(storeientry(ix, &ie) < 0){
97 fprint(2, "can't fix index: %r");
98 ok = -1;
99 }
102 if(0 && clump / 1000 != (clump + n) / 1000)
103 fprint(2, ".");
105 free(cis);
106 free(addrs);
107 free(s);
108 return ok;
111 int
112 syncindex(Index *ix, int fix)
114 Arena *arena;
115 u64int a;
116 u32int clump;
117 int i, e, e1, ok, ok1;
119 ok = 0;
120 for(i = 0; i < ix->narenas; i++){
121 arena = ix->arenas[i];
122 clump = arena->clumps;
123 a = arena->used;
124 e = syncarena(arena, TWID32, fix, fix);
125 e1 = e;
126 if(fix)
127 e1 &= ~(SyncHeader|SyncCIZero);
128 if(e1 == SyncHeader)
129 fprint(2, "arena %s: header is out-of-date\n", arena->name);
130 if(e1)
131 ok = -1;
132 else{
133 ok1 = syncarenaindex(ix, arena, clump, a + ix->amap[i].start, fix);
134 if(fix && ok1==0 && (e & SyncHeader) && wbarena(arena) < 0)
135 fprint(2, "arena=%s header write failed: %r\n", arena->name);
136 ok |= ok1;
139 if(fix && wbindex(ix) < 0){
140 fprint(2, "can't write back index header for %s: %r\n", ix->name);
141 return -1;
143 return ok;