#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;
}
