#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;
	AState as;
	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];
		/*
		 * Syncarena will scan through the arena looking for blocks
		 * that have been forgotten.  It will update arena->memstats.used,
		 * so save the currenct copy as the place to start the 
		 * syncarenaindex scan.
		 */
		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);
		clump = arena->diskstats.clumps;
		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");
fprint(2, "arena %s: wbarena in syncindex\n", arena->name);
			if(fix && ok1==0 && (e & SyncHeader) && wbarena(arena) < 0)
				fprint(2, "arena=%s header write failed: %r\n", arena->name);
			ok |= ok1;

fprint(2, "arena %s: setdcachestate\n", arena->name);
			as.arena = arena;
			as.aa = ix->amap[i].start + arena->memstats.used;
			as.stats = arena->memstats;
			setdcachestate(&as);
		}
	}
	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;
}
