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

int icacheprefetch = 1;

typedef struct ICache ICache;
typedef struct IHash IHash;
typedef struct ISum ISum;

struct ICache
{
	QLock	lock;
	Rendez	full;
	IHash	*hash;
	IEntry	*entries;
	int		nentries;
	IEntry	free;
	IEntry	clean;
	IEntry	dirty;
	u32int	maxdirty;
	u32int	ndirty;
	AState	as;

	ISum	**sum;
	int		nsum;
	IHash	*shash;
	IEntry	*sentries;
	int		nsentries;
};

static ICache icache;

/*
 * Hash table of IEntries
 */

struct IHash
{
	int bits;
	u32int size;
	IEntry **table;
};

static IHash*
mkihash(int size1)
{
	u32int size;
	int bits;
	IHash *ih;
	
	bits = 0;
	size = 1;
	while(size < size1){
		bits++;
		size <<= 1;
	}
	
	ih = vtmallocz(sizeof(IHash)+size*sizeof(ih->table[0]));
	ih->table = (IEntry**)(ih+1);
	ih->bits = bits;
	ih->size = size;
	return ih;
}

static IEntry*
ihashlookup(IHash *ih, u8int score[VtScoreSize], int type)
{
	u32int h;
	IEntry *ie;
	
	h = hashbits(score, ih->bits);
	for(ie=ih->table[h]; ie; ie=ie->nexthash)
		if((type == -1 || type == ie->ia.type) && scorecmp(score, ie->score) == 0)
			return ie;
	return nil;
}

static void
ihashdelete(IHash *ih, IEntry *ie, char *what)
{
	u32int h;
	IEntry **l;
	
	h = hashbits(ie->score, ih->bits);
	for(l=&ih->table[h]; *l; l=&(*l)->nexthash)
		if(*l == ie){
			*l = ie->nexthash;
			return;
		}
	fprint(2, "warning: %s %V not found in ihashdelete\n", what, ie->score);
}

static void
ihashinsert(IHash *ih, IEntry *ie)
{
	u32int h;
	
	h = hashbits(ie->score, ih->bits);
	ie->nexthash = ih->table[h];
	ih->table[h] = ie;
}


/*
 * IEntry lists.
 */

static IEntry*
popout(IEntry *ie)
{
	if(ie->prev == nil && ie->next == nil)
		return ie;
	ie->prev->next = ie->next;
	ie->next->prev = ie->prev;
	ie->next = nil;
	ie->prev = nil;
	return ie;
}

static IEntry*
poplast(IEntry *list)
{
	if(list->prev == list)
		return nil;
	return popout(list->prev);
}

static IEntry*
pushfirst(IEntry *list, IEntry *ie)
{
	popout(ie);
	ie->prev = list;
	ie->next = list->next;
	ie->prev->next = ie;
	ie->next->prev = ie;
	return ie;
}

/*
 * Arena summary cache.
 */
struct ISum
{
	QLock	lock;
	IEntry	*entries;
	int	nentries;
	int	loaded;
	u64int addr;
	u64int limit;
	Arena *arena;
	int g;
};

static ISum*
scachelookup(u64int addr)
{
	int i;
	ISum *s;

	for(i=0; i<icache.nsum; i++){
		s = icache.sum[i];
		if(s->addr <= addr && addr < s->limit){
			if(i > 0){
				memmove(icache.sum+1, icache.sum, i*sizeof icache.sum[0]);
				icache.sum[0] = s;
			}
			return s;
		}
	}
	return nil;
}

static void
sumclear(ISum *s)
{
	int i;

	for(i=0; i<s->nentries; i++)
		ihashdelete(icache.shash, &s->entries[i], "scache");
	s->nentries = 0;
	s->loaded = 0;
	s->addr = 0;
	s->limit = 0;
	s->arena = nil;
	s->g = 0;
}

static ISum*
scacheevict(void)
{
	ISum *s;
	int i;
	
	for(i=icache.nsum-1; i>=0; i--){
		s = icache.sum[i];
		if(canqlock(&s->lock)){
			if(i > 0){
				memmove(icache.sum+1, icache.sum, i*sizeof icache.sum[0]);
				icache.sum[0] = s;
			}
			sumclear(s);
			return s;
		}
	}
	return nil;
}

static void
scachehit(u64int addr)
{
	scachelookup(addr);	/* for move-to-front */
}

static void
scachesetup(ISum *s, u64int addr)
{
	u64int addr0, limit;
	int g;

	s->arena = amapitoag(mainindex, addr, &addr0, &limit, &g);
	s->addr = addr0;
	s->limit = limit;
	s->g = g;
}

static void
scacheload(ISum *s)
{
	int i, n;

	s->loaded = 1;
	n = asumload(s->arena, s->g, s->entries, ArenaCIGSize);
	/*
	 * n can be less then ArenaCIGSize, either if the clump group
	 * is the last in the arena and is only partially filled, or if there
	 * are corrupt clumps in the group -- those are not returned.
	 */
	for(i=0; i<n; i++){
		s->entries[i].ia.addr += s->addr;
		ihashinsert(icache.shash, &s->entries[i]);
	}
//fprint(2, "%T scacheload %s %d - %d entries\n", s->arena->name, s->g, n);
	addstat(StatScachePrefetch, n);
	s->nentries = n;
}

static ISum*
scachemiss(u64int addr)
{
	ISum *s;

	if(!icacheprefetch)
		return nil;
	s = scachelookup(addr);
	if(s == nil){
		/* first time: make an entry in the cache but don't populate it yet */
		s = scacheevict();
		if(s == nil)
			return nil;
		scachesetup(s, addr);
		qunlock(&s->lock);
		return nil;
	}

	/* second time: load from disk */
	qlock(&s->lock);
	if(s->loaded || !icacheprefetch){
		qunlock(&s->lock);
		return nil;
	}
	
	return s;	/* locked */
}

/*
 * Index cache.
 */

void
initicache(u32int mem0)
{
	u32int mem;
	int i, entries, scache;
	
	icache.full.l = &icache.lock;

	mem = mem0;
	entries = mem / (sizeof(IEntry)+sizeof(IEntry*));
	scache = (entries/8) / ArenaCIGSize;
	entries -= entries/8;
	if(scache < 4)
		scache = 4;
	if(scache > 16)
		scache = 16;
	if(entries < 1000)
		entries = 1000;
fprint(2, "icache %,d bytes = %,d entries; %d scache\n", mem0, entries, scache);

	icache.clean.prev = icache.clean.next = &icache.clean;
	icache.dirty.prev = icache.dirty.next = &icache.dirty;
	icache.free.prev = icache.free.next = &icache.free;
	
	icache.hash = mkihash(entries);
	icache.nentries = entries;
	setstat(StatIcacheSize, entries);
	icache.entries = vtmallocz(entries*sizeof icache.entries[0]);
	icache.maxdirty = entries / 2;
	for(i=0; i<entries; i++)
		pushfirst(&icache.free, &icache.entries[i]);

	icache.nsum = scache;
	icache.sum = vtmallocz(scache*sizeof icache.sum[0]);
	icache.sum[0] = vtmallocz(scache*sizeof icache.sum[0][0]);
	icache.nsentries = scache * ArenaCIGSize;
	icache.sentries = vtmallocz(scache*ArenaCIGSize*sizeof icache.sentries[0]);
	icache.shash = mkihash(scache*ArenaCIGSize);
	for(i=0; i<scache; i++){
		icache.sum[i] = icache.sum[0] + i;
		icache.sum[i]->entries = icache.sentries + i*ArenaCIGSize;
	}
}


static IEntry*
evictlru(void)
{
	IEntry *ie;
	
	ie = poplast(&icache.clean);
	if(ie == nil)
		return nil;
	ihashdelete(icache.hash, ie, "evictlru");
	return ie;
}

static void
icacheinsert(u8int score[VtScoreSize], IAddr *ia, int state)
{
	IEntry *ie;

	if((ie = poplast(&icache.free)) == nil && (ie = evictlru()) == nil){
		addstat(StatIcacheStall, 1);
		while((ie = poplast(&icache.free)) == nil && (ie = evictlru()) == nil){
			// Could safely return here if state == IEClean.
			// But if state == IEDirty, have to wait to make
			// sure we don't lose an index write.  
			// Let's wait all the time.
			flushdcache();
			kickicache();
			rsleep(&icache.full);
		}
		addstat(StatIcacheStall, -1);
	}

	memmove(ie->score, score, VtScoreSize);
	ie->state = state;
	ie->ia = *ia;
	if(state == IEClean){
		addstat(StatIcachePrefetch, 1);
		pushfirst(&icache.clean, ie);
	}else{
		addstat(StatIcacheWrite, 1);
		assert(state == IEDirty);
		icache.ndirty++;
		setstat(StatIcacheDirty, icache.ndirty);
		delaykickicache();
		pushfirst(&icache.dirty, ie);
	}
	ihashinsert(icache.hash, ie);
}

int
icachelookup(u8int score[VtScoreSize], int type, IAddr *ia)
{
	IEntry *ie;

	qlock(&icache.lock);
	addstat(StatIcacheLookup, 1);
	if((ie = ihashlookup(icache.hash, score, type)) != nil){
		*ia = ie->ia;
		if(ie->state == IEClean)
			pushfirst(&icache.clean, ie);
		addstat(StatIcacheHit, 1);
		qunlock(&icache.lock);
		return 0;
	}

	if((ie = ihashlookup(icache.shash, score, type)) != nil){
		*ia = ie->ia;
		icacheinsert(score, &ie->ia, IEClean);
		scachehit(ie->ia.addr);
		addstat(StatScacheHit, 1);
		qunlock(&icache.lock);
		return 0;
	}
	addstat(StatIcacheMiss, 1);
	qunlock(&icache.lock);

	return -1;
}

int
insertscore(u8int score[VtScoreSize], IAddr *ia, int state, AState *as)
{
	ISum *toload;

	qlock(&icache.lock);
	icacheinsert(score, ia, state);
	if(state == IEClean)
		toload = scachemiss(ia->addr);
	else{
		assert(state == IEDirty);
		toload = nil;
		if(as == nil)
			fprint(2, "%T insertscore IEDirty without as; called from %lux\n", getcallerpc(&score));
		else{
			if(icache.as.aa > as->aa)
				fprint(2, "%T insertscore: aa moving backward: %#llux -> %#llux\n", icache.as.aa, as->aa);
			icache.as = *as;
		}
	}
	qunlock(&icache.lock);
	if(toload){
		scacheload(toload);
		qunlock(&toload->lock);
	}
	
	if(icache.ndirty >= icache.maxdirty)
		kickicache();

	/*
	 * It's okay not to do this under icache.lock.
	 * Calling insertscore only happens when we hold
	 * the lump, meaning any searches for this block
	 * will hit in the lump cache until after we return.
	 */
	if(state == IEDirty)
		markbloomfilter(mainindex->bloom, score);

	return 0;
}

int
lookupscore(u8int score[VtScoreSize], int type, IAddr *ia)
{
	int ms, ret;
	IEntry d;

	if(icachelookup(score, type, ia) >= 0){
		addstat(StatIcacheRead, 1);
		return 0;
	}

	ms = msec();
	addstat(StatIcacheFill, 1);
	if(loadientry(mainindex, score, type, &d) < 0)
		ret = -1;
	else{
		ret = 0;
		insertscore(score, &d.ia, IEClean, nil);
		*ia = d.ia;
	}
	addstat2(StatIcacheRead, 1, StatIcacheReadTime, msec() - ms);
	return ret;
}
	
u32int
hashbits(u8int *sc, int bits)
{
	u32int v;

	v = (sc[0] << 24) | (sc[1] << 16) | (sc[2] << 8) | sc[3];
	if(bits < 32)
		 v >>= (32 - bits);
	return v;
}

ulong
icachedirtyfrac(void)
{
	return (vlong)icache.ndirty*IcacheFrac / icache.nentries;
}

/*
 * Return a singly-linked list of dirty index entries.
 * with 32-bit hash numbers between lo and hi
 * and address < limit.
 */
IEntry*
icachedirty(u32int lo, u32int hi, u64int limit)
{
	u32int h;
	IEntry *ie, *dirty;

	dirty = nil;
	trace(TraceProc, "icachedirty enter");
	qlock(&icache.lock);
	for(ie = icache.dirty.next; ie != &icache.dirty; ie=ie->next){
		if(ie->state == IEDirty && ie->ia.addr <= limit){
			h = hashbits(ie->score, 32);
			if(lo <= h && h <= hi){
				ie->nextdirty = dirty;
				dirty = ie;
			}
		}
	}
	qunlock(&icache.lock);
	trace(TraceProc, "icachedirty exit");
	if(dirty == nil)
		flushdcache();
	return dirty;
}

AState
icachestate(void)
{
	AState as;

	qlock(&icache.lock);
	as = icache.as;
	qunlock(&icache.lock);
	return as;
}

/*
 * The singly-linked non-circular list of index entries ie
 * has been written to disk.  Move them to the clean list.
 */
void
icacheclean(IEntry *ie)
{
	IEntry *next;
	
	trace(TraceProc, "icacheclean enter");
	qlock(&icache.lock);
	for(; ie; ie=next){
		assert(ie->state == IEDirty);
		next = ie->nextdirty;
		ie->nextdirty = nil;
		popout(ie); /* from icache.dirty */
		icache.ndirty--;
		ie->state = IEClean;
		pushfirst(&icache.clean, ie);
	}
	setstat(StatIcacheDirty, icache.ndirty);
	rwakeupall(&icache.full);
	qunlock(&icache.lock);
	trace(TraceProc, "icacheclean exit");
}

void
emptyicache(void)
{
	int i;
	IEntry *ie;
	ISum *s;
	
	qlock(&icache.lock);
	while((ie = evictlru()) != nil)
		pushfirst(&icache.free, ie);
	for(i=0; i<icache.nsum; i++){
		s = icache.sum[i];
		qlock(&s->lock);
		sumclear(s);
		qunlock(&s->lock);
	}
	qunlock(&icache.lock);
}

