syncindex0.c 3.0 KB

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