#include "stdinc.h"
#include "dat.h"
#include "fns.h"

enum
{
	ClumpChunks	= 32*1024
};

static int missing, wrong;

/*
 * 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, int *pflush, int check)
{
	Packet *pack;
	IEntry ie;
	IAddr ia;
	ClumpInfo *ci, *cis;
	u64int *addrs;
	int i, n, ok, *s, flush;

	trace(TraceProc, "syncarenaindex enter");

	flush = 0;
	cis = MKN(ClumpInfo, ClumpChunks);
	addrs = MKN(u64int, ClumpChunks);
	s = MKN(int, ClumpChunks);
	ok = 0;
	for(; clump < arena->memstats.clumps; clump += n){
		n = ClumpChunks;
		if(n > arena->memstats.clumps - clump)
			n = arena->memstats.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(!check)
				goto Add;
			if(loadientry(ix, ci->score, ci->type, &ie) < 0){
				trace(TraceProc, "syncarenaindex missing block %V.%d", ci->score, ci->type);
				missing++;
			if(0)	fprint(2, "missing block type=%d score=%V\n", ci->type, ci->score);
			}else if(iaddrcmp(&ia, &ie.ia) != 0){
				trace(TraceProc, "syncarenaindex mismatched entry");
				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, nil);
				packetfree(pack);
				if(pack != nil){
					fprint(2, "duplicated lump\n");
					continue;
				}
				wrong++;
			}else
				continue;
		Add:
			if(!fix){
				ok = -1;
				continue;
			}
			flush = 1;
			trace(TraceProc, "syncarenaindex insert %V", ci->score);
			insertscore(ci->score, &ia, 1);
		}

		if(0 && clump / 1000 != (clump + n) / 1000)
			fprint(2, ".");
	}
	free(cis);
	free(addrs);
	free(s);
	if(flush){
		flushdcache();
		*pflush = 1;
	}
	return ok;
}

int
syncindex(Index *ix, int fix, int mustflush, int check)
{
	Arena *arena;
	u64int a;
	u32int clump;
	int i, e, e1, ok, ok1, flush;

	ok = 0;
	flush = 0;
	for(i = 0; i < ix->narenas; i++){
		trace(TraceProc, "syncindex start %d", i);
		arena = ix->arenas[i];
		clump = arena->memstats.clumps;
		a = arena->memstats.used;
		e = syncarena(arena, ix->amap[i].start, TWID32, fix, fix);
		e1 = e;
		if(fix)
			e1 &= ~(SyncHeader|SyncCIZero|SyncCIErr);
		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, &flush, check);
			if(ok1 < 0)
				fprint(2, "syncarenaindex: %r\n");
			if(fix && ok1==0 && (e & SyncHeader) && wbarena(arena) < 0)
				fprint(2, "arena=%s header write failed: %r\n", arena->name);
			ok |= ok1;
		}
	}
	if(missing || wrong)
		fprint(2, "syncindex: %d missing entries, %d wrong entries (flush=%d)\n", missing, wrong, flush);
	if(fix && wbindex(ix) < 0){
		fprint(2, "can't write back index header for %s: %r\n", ix->name);
		return -1;
	}
	if(fix && flush){
		flushdcache();
		if(mustflush){
			flushicache();
			flushdcache();
		}else
			kickicache();
	}
	return ok;
}
