#include <u.h>
#include <libc.h>
#include <diskfs.h>

/*
 * Disk cache.  Caches by offset, so higher levels have 
 * to deal with alignment issues (if we get asked for the
 * blocks at offsets 0 and 1, we'll do two reads.
 */

typedef struct DiskCache DiskCache;
typedef struct DiskCacheBlock DiskCacheBlock;

struct DiskCache
{
	Disk disk;
	Disk *subdisk;
	DiskCacheBlock **h;
	DiskCacheBlock *lruhead;
	DiskCacheBlock *lrutail;
	int nhash;
	int blocksize;
	Lock lk;
};

struct DiskCacheBlock
{
	Block block;
	Block *subblock;
	Lock lk;
	int ref;
	DiskCache *dc;
	DiskCacheBlock *next;
	DiskCacheBlock *lrunext;
	DiskCacheBlock *lruprev;
	u64int offset;
};

static void
addtohash(DiskCache *d, DiskCacheBlock *b, u64int offset)
{
	int h;

	if(b->offset != ~(u64int)0){
		fprint(2, "bad offset in addtohash\n");
		return;	
	}
	b->offset = offset;
	h = offset % d->nhash;
	b->next = d->h[h];
	d->h[h] = b;
}

static void
delfromhash(DiskCache *d, DiskCacheBlock *b)
{
	int h;
	DiskCacheBlock **l;

	if(b->offset == ~(u64int)0)
		return;

	h = b->offset % d->nhash;
	for(l=&d->h[h]; *l; l=&(*l)->next)
		if(*l == b){
			*l = b->next;
			b->offset = ~(u64int)0;
			return;
		}
	fprint(2, "delfromhash: didn't find in hash table\n");
	return;
}

static void
putmru(DiskCache *d, DiskCacheBlock *b)
{
	b->lruprev = nil;
	b->lrunext = d->lruhead;
	d->lruhead = b;
	if(b->lrunext == nil)
		d->lrutail = b;
	else
		b->lrunext->lruprev = b;
}

static void
putlru(DiskCache *d, DiskCacheBlock *b)
{
	b->lruprev = d->lrutail;
	b->lrunext = nil;
	d->lrutail = b;
	if(b->lruprev == nil)
		d->lruhead = b;
	else
		b->lruprev->lrunext = b;
}

static void
delfromlru(DiskCache *d, DiskCacheBlock *b)
{
	if(b->lruprev)
		b->lruprev->lrunext = b->lrunext;
	else
		d->lruhead = b->lrunext;
	if(b->lrunext)
		b->lrunext->lruprev = b->lruprev;
	else
		d->lrutail = b->lruprev;
}

static DiskCacheBlock*
getlru(DiskCache *d)
{
	DiskCacheBlock *b;

	b = d->lrutail;
	if(b){
		delfromlru(d, b);
		delfromhash(d, b);
		blockput(b->subblock);
		b->subblock = nil;
	}
	return b;
}

static DiskCacheBlock*
findblock(DiskCache *d, u64int offset)
{
	int h;
	DiskCacheBlock *b;

	h = offset % d->nhash;
	for(b=d->h[h]; b; b=b->next)
		if(b->offset == offset)
			return b;
	return nil;
}

static DiskCacheBlock*
diskcachereadbig(DiskCache *d, u64int offset)
{
	Block *b;
	DiskCacheBlock *dcb;

	lock(&d->lk);
	dcb = findblock(d, offset);
	if(dcb){
/*fprint(2, "found %llud in cache %p\n", (uvlong)offset, dcb);*/
		if(dcb->ref++ == 0)
			delfromlru(d, dcb);
		unlock(&d->lk);
		return dcb;
	}

	dcb = getlru(d);
	unlock(&d->lk);
	if(dcb == nil){
		fprint(2, "diskcacheread: all blocks in use\n");
		return nil;
	}

	b = diskread(d->subdisk, d->blocksize, offset);
	lock(&d->lk);
	if(b == nil){
		putlru(d, dcb);
		dcb = nil;
	}else{
/*fprint(2, "read %llud from disk %p\n", (uvlong)offset, dcb); */
		dcb->subblock = b;
		dcb->ref++;
		addtohash(d, dcb, offset);
	}
	unlock(&d->lk);
	return dcb;
}

static void
diskcacheblockclose(Block *bb)
{
	DiskCacheBlock *b = bb->priv;

	lock(&b->dc->lk);
	if(--b->ref == 0)
		putmru(b->dc, b);
	unlock(&b->dc->lk);
	free(bb);
}

static Block*
diskcacheread(Disk *dd, u32int len, u64int offset)
{
	int frag, dlen;
	DiskCache *d = (DiskCache*)dd;
	DiskCacheBlock *dcb;
	Block *b;

	if(offset/d->blocksize != (offset+len-1)/d->blocksize){
		fprint(2, "diskBigRead: request for block crossing big block boundary\n");
		return nil;
	}

	b = mallocz(sizeof(Block), 1);
	if(b == nil)
		return nil;

	frag = offset%d->blocksize;

	dcb = diskcachereadbig(d, offset-frag);
	if(dcb == nil){
		free(b);
		return nil;
	}
	b->priv = dcb;
	b->_close = diskcacheblockclose;
	b->data = dcb->subblock->data+frag;

	dlen = dcb->subblock->len;
	if(frag+len >= dlen){
		if(frag >= dlen){
			blockput(b);
			return nil;
		}
		len = dlen-frag;
	}
	b->len = len;
/*fprint(2, "offset %llud at pointer %p %lux\n", (uvlong)offset, b->data, *(ulong*)(b->data+4)); */
	return b;
}

/* 
 * It's okay to remove these from the hash table. 
 * Either the block is in use by someone or it is on
 * the lru list.  If it's in use it will get put on the lru
 * list once the refs go away.
 */
static int
diskcachesync(Disk *dd)
{
	DiskCache *d = (DiskCache*)dd;
	DiskCacheBlock *b, *nextb;
	int i;

	lock(&d->lk);
	for(i=0; i<d->nhash; i++){
		for(b=d->h[i]; b; b=nextb){
			nextb = b->next;
			b->next = nil;
			b->offset = ~(u64int)0;
		}
		d->h[i] = nil;
	}
	unlock(&d->lk);
	return disksync(d->subdisk);
}

static void
diskcacheclose(Disk *dd)
{
	DiskCacheBlock *b;
	DiskCache *d = (DiskCache*)dd;

	diskclose(d->subdisk);
	for(b=d->lruhead; b; b=b->lrunext)
		blockput(b->subblock);
	free(d);
}
		
/* needn't be fast */
static int
isprime(int n)
{
	int i;

	for(i=2; i*i<=n; i++)
		if(n%i == 0)
			return 0;
	return 1;
}

Disk*
diskcache(Disk *subdisk, uint blocksize, uint ncache)
{
	int nhash, i;
	DiskCache *d;
	DiskCacheBlock *b;

	nhash = ncache;
	while(nhash > 1 && !isprime(nhash))
		nhash--;
	d = mallocz(sizeof(DiskCache)+ncache*sizeof(DiskCacheBlock)+nhash*sizeof(DiskCacheBlock*), 1);
	if(d == nil)
		return nil;

	b = (DiskCacheBlock*)&d[1];
	d->h = (DiskCacheBlock**)&b[ncache];
	d->nhash = nhash;
	d->blocksize = blocksize;
	d->subdisk = subdisk;
	d->disk._read = diskcacheread;
	d->disk._sync = diskcachesync;
	d->disk._close = diskcacheclose;

	for(i=0; i<ncache; i++){
		b[i].block._close = diskcacheblockclose;
		b[i].offset = ~(u64int)0;
		b[i].dc = d;
		putlru(d, &b[i]);
	}

	return &d->disk;
}
