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

static int	sizeToDepth(uvlong s, int psize, int dsize);
static u32int 	tagGen(void);
static Block 	*sourceLoad(Source *r, Entry *e);
static int	sourceShrinkDepth(Source*, Block*, Entry*, int);
static int	sourceShrinkSize(Source*, Entry*, uvlong);
static int	sourceGrowDepth(Source*, Block*, Entry*, int);

#define sourceIsLocked(r)	((r)->b != nil)

static Source *
sourceAlloc(Fs *fs, Block *b, Source *p, u32int offset, int mode, int issnapshot)
{
	int epb;
	u32int epoch;
	char *pname = nil;
	Source *r;
	Entry e;

	assert(p==nil || sourceIsLocked(p));

	if(p == nil){
		assert(offset == 0);
		epb = 1;
	}else
		epb = p->dsize / VtEntrySize;

	if(b->l.type != BtDir)
		goto Bad;

	/*
	 * a non-active entry is the only thing that
	 * can legitimately happen here. all the others
	 * get prints.
	 */
	if(!entryUnpack(&e, b->data, offset % epb)){
		pname = sourceName(p);
		consPrint("%s: %s %V: sourceAlloc: entryUnpack failed\n",
			fs->name, pname, b->score);
		goto Bad;
	}
	if(!(e.flags & VtEntryActive)){
		pname = sourceName(p);
		if(0) consPrint("%s: %s %V: sourceAlloc: not active\n",
			fs->name, pname, e.score);
		goto Bad;
	}
	if(e.psize < 256 || e.dsize < 256){
		pname = sourceName(p);
		consPrint("%s: %s %V: sourceAlloc: psize %ud or dsize %ud < 256\n",
			fs->name, pname, e.score, e.psize, e.dsize);
		goto Bad;
	}

	if(e.depth < sizeToDepth(e.size, e.psize, e.dsize)){
		pname = sourceName(p);
		consPrint("%s: %s %V: sourceAlloc: depth %ud size %llud "
			"psize %ud dsize %ud\n", fs->name, pname,
			e.score, e.depth, e.size, e.psize, e.dsize);
		goto Bad;
	}

	if((e.flags & VtEntryLocal) && e.tag == 0){
		pname = sourceName(p);
		consPrint("%s: %s %V: sourceAlloc: flags %#ux tag %#ux\n",
			fs->name, pname, e.score, e.flags, e.tag);
		goto Bad;
	}

	if(e.dsize > fs->blockSize || e.psize > fs->blockSize){
		pname = sourceName(p);
		consPrint("%s: %s %V: sourceAlloc: psize %ud or dsize %ud "
			"> blocksize %ud\n", fs->name, pname, e.score,
			e.psize, e.dsize, fs->blockSize);
		goto Bad;
	}

	epoch = b->l.epoch;
	if(mode == OReadWrite){
		if(e.snap != 0){
			werrstr(ESnapRO);
			return nil;
		}
	}else if(e.snap != 0){
		if(e.snap < fs->elo){
			werrstr(ESnapOld);
			return nil;
		}
		if(e.snap >= fs->ehi)
			goto Bad;
		epoch = e.snap;
	}

	r = vtmallocz(sizeof(Source));
	r->fs = fs;
	r->mode = mode;
	r->issnapshot = issnapshot;
	r->dsize = e.dsize;
	r->gen = e.gen;
	r->dir = (e.flags & _VtEntryDir) != 0;
	r->ref = 1;
	r->parent = p;
	if(p){
		qlock(&p->lk);
		assert(mode == OReadOnly || p->mode == OReadWrite);
		p->ref++;
		qunlock(&p->lk);
	}
	r->epoch = epoch;
//	consPrint("sourceAlloc: have %V be.%d fse.%d %s\n", b->score,
//		b->l.epoch, r->fs->ehi, mode == OReadWrite? "rw": "ro");
	memmove(r->score, b->score, VtScoreSize);
	r->scoreEpoch = b->l.epoch;
	r->offset = offset;
	r->epb = epb;
	r->tag = b->l.tag;

//	consPrint("%s: sourceAlloc: %p -> %V %d\n", r, r->score, r->offset);

	return r;
Bad:
	free(pname);
	werrstr(EBadEntry);
	return nil;
}

Source *
sourceRoot(Fs *fs, u32int addr, int mode)
{
	Source *r;
	Block *b;

	b = cacheLocalData(fs->cache, addr, BtDir, RootTag, mode, 0);
	if(b == nil)
		return nil;

	if(mode == OReadWrite && b->l.epoch != fs->ehi){
		consPrint("sourceRoot: fs->ehi = %ud, b->l = %L\n",
			fs->ehi, &b->l);
		blockPut(b);
		werrstr(EBadRoot);
		return nil;
	}

	r = sourceAlloc(fs, b, nil, 0, mode, 0);
	blockPut(b);
	return r;
}

Source *
sourceOpen(Source *r, ulong offset, int mode, int issnapshot)
{
	ulong bn;
	Block *b;

	assert(sourceIsLocked(r));
	if(r->mode == OReadWrite)
		assert(r->epoch == r->b->l.epoch);
	if(!r->dir){
		werrstr(ENotDir);
		return nil;
	}

	bn = offset/(r->dsize/VtEntrySize);

	b = sourceBlock(r, bn, mode);
	if(b == nil)
		return nil;
	r = sourceAlloc(r->fs, b, r, offset, mode, issnapshot);
	blockPut(b);
	return r;
}

Source *
sourceCreate(Source *r, int dsize, int dir, u32int offset)
{
	int i, epb, psize;
	u32int bn, size;
	Block *b;
	Entry e;
	Source *rr;

	assert(sourceIsLocked(r));

	if(!r->dir){
		werrstr(ENotDir);
		return nil;
	}

	epb = r->dsize/VtEntrySize;
	psize = (dsize/VtScoreSize)*VtScoreSize;

	size = sourceGetDirSize(r);
	if(offset == 0){
		/*
		 * look at a random block to see if we can find an empty entry
		 */
		offset = lnrand(size+1);
		offset -= offset % epb;
	}

	/* try the given block and then try the last block */
	for(;;){
		bn = offset/epb;
		b = sourceBlock(r, bn, OReadWrite);
		if(b == nil)
			return nil;
		for(i=offset%r->epb; i<epb; i++){
			entryUnpack(&e, b->data, i);
			if((e.flags&VtEntryActive) == 0 && e.gen != ~0)
				goto Found;
		}
		blockPut(b);
		if(offset == size){
			fprint(2, "sourceCreate: cannot happen\n");
			werrstr("sourceCreate: cannot happen");
			return nil;
		}
		offset = size;
	}

Found:
	/* found an entry - gen already set */
	e.psize = psize;
	e.dsize = dsize;
	assert(psize && dsize);
	e.flags = VtEntryActive;
	if(dir)
		e.flags |= _VtEntryDir;
	e.depth = 0;
	e.size = 0;
	memmove(e.score, vtzeroscore, VtScoreSize);
	e.tag = 0;
	e.snap = 0;
	e.archive = 0;
	entryPack(&e, b->data, i);
	blockDirty(b);

	offset = bn*epb + i;
	if(offset+1 > size){
		if(!sourceSetDirSize(r, offset+1)){
			blockPut(b);
			return nil;
		}
	}

	rr = sourceAlloc(r->fs, b, r, offset, OReadWrite, 0);
	blockPut(b);
	return rr;
}

static int
sourceKill(Source *r, int doremove)
{
	Entry e;
	Block *b;
	u32int addr;
	u32int tag;
	int type;

	assert(sourceIsLocked(r));
	b = sourceLoad(r, &e);
	if(b == nil)
		return 0;

	assert(b->l.epoch == r->fs->ehi);

	if(doremove==0 && e.size == 0){
		/* already truncated */
		blockPut(b);
		return 1;
	}

	/* remember info on link we are removing */
	addr = globalToLocal(e.score);
	type = entryType(&e);
	tag = e.tag;

	if(doremove){
		if(e.gen != ~0)
			e.gen++;
		e.dsize = 0;
		e.psize = 0;
		e.flags = 0;
	}else{
		e.flags &= ~VtEntryLocal;
	}
	e.depth = 0;
	e.size = 0;
	e.tag = 0;
	memmove(e.score, vtzeroscore, VtScoreSize);
	entryPack(&e, b->data, r->offset % r->epb);
	blockDirty(b);
	if(addr != NilBlock)
		blockRemoveLink(b, addr, type, tag, 1);
	blockPut(b);

	if(doremove){
		sourceUnlock(r);
		sourceClose(r);
	}

	return 1;
}

int
sourceRemove(Source *r)
{
	return sourceKill(r, 1);
}

int
sourceTruncate(Source *r)
{
	return sourceKill(r, 0);
}

uvlong
sourceGetSize(Source *r)
{
	Entry e;
	Block *b;

	assert(sourceIsLocked(r));
	b = sourceLoad(r, &e);
	if(b == nil)
		return 0;
	blockPut(b);

	return e.size;
}

static int
sourceShrinkSize(Source *r, Entry *e, uvlong size)
{
	int i, type, ppb;
	uvlong ptrsz;
	u32int addr;
	uchar score[VtScoreSize];
	Block *b;

	type = entryType(e);
	b = cacheGlobal(r->fs->cache, e->score, type, e->tag, OReadWrite);
	if(b == nil)
		return 0;

	ptrsz = e->dsize;
	ppb = e->psize/VtScoreSize;
	for(i=0; i+1<e->depth; i++)
		ptrsz *= ppb;

	while(type&BtLevelMask){
		if(b->addr == NilBlock || b->l.epoch != r->fs->ehi){
			/* not worth copying the block just so we can zero some of it */
			blockPut(b);
			return 0;
		}

		/*
		 * invariant: each pointer in the tree rooted at b accounts for ptrsz bytes
		 */

		/* zero the pointers to unnecessary blocks */
		i = (size+ptrsz-1)/ptrsz;
		for(; i<ppb; i++){
			addr = globalToLocal(b->data+i*VtScoreSize);
			memmove(b->data+i*VtScoreSize, vtzeroscore, VtScoreSize);
			blockDirty(b);
			if(addr != NilBlock)
				blockRemoveLink(b, addr, type-1, e->tag, 1);
		}

		/* recurse (go around again) on the partially necessary block */
		i = size/ptrsz;
		size = size%ptrsz;
		if(size == 0){
			blockPut(b);
			return 1;
		}
		ptrsz /= ppb;
		type--;
		memmove(score, b->data+i*VtScoreSize, VtScoreSize);
		blockPut(b);
		b = cacheGlobal(r->fs->cache, score, type, e->tag, OReadWrite);
		if(b == nil)
			return 0;
	}

	if(b->addr == NilBlock || b->l.epoch != r->fs->ehi){
		blockPut(b);
		return 0;
	}

	/*
	 * No one ever truncates BtDir blocks.
	 */
	if(type == BtData && e->dsize > size){
		memset(b->data+size, 0, e->dsize-size);
		blockDirty(b);
	}
	blockPut(b);
	return 1;
}

int
sourceSetSize(Source *r, uvlong size)
{
	int depth;
	Entry e;
	Block *b;

	assert(sourceIsLocked(r));
	if(size == 0)
		return sourceTruncate(r);

	if(size > VtMaxFileSize || size > ((uvlong)MaxBlock)*r->dsize){
		werrstr(ETooBig);
		return 0;
	}

	b = sourceLoad(r, &e);
	if(b == nil)
		return 0;

	/* quick out */
	if(e.size == size){
		blockPut(b);
		return 1;
	}

	depth = sizeToDepth(size, e.psize, e.dsize);

	if(depth < e.depth){
		if(!sourceShrinkDepth(r, b, &e, depth)){
			blockPut(b);
			return 0;
		}
	}else if(depth > e.depth){
		if(!sourceGrowDepth(r, b, &e, depth)){
			blockPut(b);
			return 0;
		}
	}

	if(size < e.size)
		sourceShrinkSize(r, &e, size);

	e.size = size;
	entryPack(&e, b->data, r->offset % r->epb);
	blockDirty(b);
	blockPut(b);

	return 1;
}

int
sourceSetDirSize(Source *r, ulong ds)
{
	uvlong size;
	int epb;

	assert(sourceIsLocked(r));
	epb = r->dsize/VtEntrySize;

	size = (uvlong)r->dsize*(ds/epb);
	size += VtEntrySize*(ds%epb);
	return sourceSetSize(r, size);
}

ulong
sourceGetDirSize(Source *r)
{
	ulong ds;
	uvlong size;
	int epb;

	assert(sourceIsLocked(r));
	epb = r->dsize/VtEntrySize;

	size = sourceGetSize(r);
	ds = epb*(size/r->dsize);
	ds += (size%r->dsize)/VtEntrySize;
	return ds;
}

int
sourceGetEntry(Source *r, Entry *e)
{
	Block *b;

	assert(sourceIsLocked(r));
	b = sourceLoad(r, e);
	if(b == nil)
		return 0;
	blockPut(b);

	return 1;
}

/*
 * Must be careful with this.  Doesn't record
 * dependencies, so don't introduce any!
 */
int
sourceSetEntry(Source *r, Entry *e)
{
	Block *b;
	Entry oe;

	assert(sourceIsLocked(r));
	b = sourceLoad(r, &oe);
	if(b == nil)
		return 0;
	entryPack(e, b->data, r->offset%r->epb);
	blockDirty(b);
	blockPut(b);

	return 1;
}

static Block *
blockWalk(Block *p, int index, int mode, Fs *fs, Entry *e)
{
	Block *b;
	Cache *c;
	u32int addr;
	int type;
	uchar oscore[VtScoreSize], score[VtScoreSize];
	Entry oe;

	c = fs->cache;

	if((p->l.type & BtLevelMask) == 0){
		assert(p->l.type == BtDir);
		type = entryType(e);
		b = cacheGlobal(c, e->score, type, e->tag, mode);
	}else{
		type = p->l.type - 1;
		b = cacheGlobal(c, p->data + index*VtScoreSize, type, e->tag, mode);
	}

	if(b)
		b->pc = getcallerpc(&p);

	if(b == nil || mode == OReadOnly)
		return b;

	if(p->l.epoch != fs->ehi){
		fprint(2, "blockWalk: parent not writable\n");
		abort();
	}
	if(b->l.epoch == fs->ehi)
		return b;

	oe = *e;

	/*
	 * Copy on write.
	 */
	if(e->tag == 0){
		assert(p->l.type == BtDir);
		e->tag = tagGen();
		e->flags |= VtEntryLocal;
	}

	addr = b->addr;
	b = blockCopy(b, e->tag, fs->ehi, fs->elo);
	if(b == nil)
		return nil;

	b->pc = getcallerpc(&p);
	assert(b->l.epoch == fs->ehi);

	blockDirty(b);
	memmove(score, b->score, VtScoreSize);
	if(p->l.type == BtDir){
		memmove(e->score, b->score, VtScoreSize);
		entryPack(e, p->data, index);
		blockDependency(p, b, index, nil, &oe);
	}else{
		memmove(oscore, p->data+index*VtScoreSize, VtScoreSize);
		memmove(p->data+index*VtScoreSize, b->score, VtScoreSize);
		blockDependency(p, b, index, oscore, nil);
	}
	blockDirty(p);

	if(addr != NilBlock)
		blockRemoveLink(p, addr, type, e->tag, 0);

	return b;
}

/*
 * Change the depth of the source r.
 * The entry e for r is contained in block p.
 */
static int
sourceGrowDepth(Source *r, Block *p, Entry *e, int depth)
{
	Block *b, *bb;
	u32int tag;
	int type;
	Entry oe;

	assert(sourceIsLocked(r));
	assert(depth <= VtPointerDepth);

	type = entryType(e);
	b = cacheGlobal(r->fs->cache, e->score, type, e->tag, OReadWrite);
	if(b == nil)
		return 0;

	tag = e->tag;
	if(tag == 0)
		tag = tagGen();

	oe = *e;

	/*
	 * Keep adding layers until we get to the right depth
	 * or an error occurs.
	 */
	while(e->depth < depth){
		bb = cacheAllocBlock(r->fs->cache, type+1, tag, r->fs->ehi, r->fs->elo);
		if(bb == nil)
			break;
//fprint(2, "alloc %lux grow %V\n", bb->addr, b->score);
		memmove(bb->data, b->score, VtScoreSize);
		memmove(e->score, bb->score, VtScoreSize);
		e->depth++;
		type++;
		e->tag = tag;
		e->flags |= VtEntryLocal;
		blockDependency(bb, b, 0, vtzeroscore, nil);
		blockPut(b);
		b = bb;
		blockDirty(b);
	}

	entryPack(e, p->data, r->offset % r->epb);
	blockDependency(p, b, r->offset % r->epb, nil, &oe);
	blockPut(b);
	blockDirty(p);

	return e->depth == depth;
}

static int
sourceShrinkDepth(Source *r, Block *p, Entry *e, int depth)
{
	Block *b, *nb, *ob, *rb;
	u32int tag;
	int type, d;
	Entry oe;

	assert(sourceIsLocked(r));
	assert(depth <= VtPointerDepth);

	type = entryType(e);
	rb = cacheGlobal(r->fs->cache, e->score, type, e->tag, OReadWrite);
	if(rb == nil)
		return 0;

	tag = e->tag;
	if(tag == 0)
		tag = tagGen();

	/*
	 * Walk down to the new root block.
	 * We may stop early, but something is better than nothing.
	 */
	oe = *e;

	ob = nil;
	b = rb;
/* BUG: explain type++.  i think it is a real bug */
	for(d=e->depth; d > depth; d--, type++){
		nb = cacheGlobal(r->fs->cache, b->data, type-1, tag, OReadWrite);
		if(nb == nil)
			break;
		if(ob!=nil && ob!=rb)
			blockPut(ob);
		ob = b;
		b = nb;
	}

	if(b == rb){
		blockPut(rb);
		return 0;
	}

	/*
	 * Right now, e points at the root block rb, b is the new root block,
	 * and ob points at b.  To update:
	 *
	 *	(i) change e to point at b
	 *	(ii) zero the pointer ob -> b
	 *	(iii) free the root block
	 *
	 * p (the block containing e) must be written before
	 * anything else.
 	 */

	/* (i) */
	e->depth = d;
	/* might have been local and now global; reverse cannot happen */
	if(globalToLocal(b->score) == NilBlock)
		e->flags &= ~VtEntryLocal;
	memmove(e->score, b->score, VtScoreSize);
	entryPack(e, p->data, r->offset % r->epb);
	blockDependency(p, b, r->offset % r->epb, nil, &oe);
	blockDirty(p);

	/* (ii) */
	memmove(ob->data, vtzeroscore, VtScoreSize);
	blockDependency(ob, p, 0, b->score, nil);
	blockDirty(ob);

	/* (iii) */
	if(rb->addr != NilBlock)
		blockRemoveLink(p, rb->addr, rb->l.type, rb->l.tag, 1);

	blockPut(rb);
	if(ob!=nil && ob!=rb)
		blockPut(ob);
	blockPut(b);

	return d == depth;
}

/*
 * Normally we return the block at the given number.
 * If early is set, we stop earlier in the tree.  Setting early
 * to 1 gives us the block that contains the pointer to bn.
 */
Block *
_sourceBlock(Source *r, ulong bn, int mode, int early, ulong tag)
{
	Block *b, *bb;
	int index[VtPointerDepth+1];
	Entry e;
	int i, np;
	int m;

	assert(sourceIsLocked(r));
	assert(bn != NilBlock);

	/* mode for intermediate block */
	m = mode;
	if(m == OOverWrite)
		m = OReadWrite;

	b = sourceLoad(r, &e);
	if(b == nil)
		return nil;
	if(r->issnapshot && (e.flags & VtEntryNoArchive)){
		blockPut(b);
		werrstr(ENotArchived);
		return nil;
	}

	if(tag){
		if(e.tag == 0)
			e.tag = tag;
		else if(e.tag != tag){
			fprint(2, "tag mismatch\n");
			werrstr("tag mismatch");
			goto Err;
		}
	}

	np = e.psize/VtScoreSize;
	memset(index, 0, sizeof(index));
	for(i=0; bn > 0; i++){
		if(i >= VtPointerDepth){
			werrstr(EBadAddr);
			goto Err;
		}
		index[i] = bn % np;
		bn /= np;
	}

	if(i > e.depth){
		if(mode == OReadOnly){
			werrstr(EBadAddr);
			goto Err;
		}
		if(!sourceGrowDepth(r, b, &e, i))
			goto Err;
	}

	index[e.depth] = r->offset % r->epb;

	for(i=e.depth; i>=early; i--){
		bb = blockWalk(b, index[i], m, r->fs, &e);
		if(bb == nil)
			goto Err;
		blockPut(b);
		b = bb;
	}
	b->pc = getcallerpc(&r);
	return b;
Err:
	blockPut(b);
	return nil;
}

Block*
sourceBlock(Source *r, ulong bn, int mode)
{
	Block *b;

	b = _sourceBlock(r, bn, mode, 0, 0);
	if(b)
		b->pc = getcallerpc(&r);
	return b;
}

void
sourceClose(Source *r)
{
	if(r == nil)
		return;
	qlock(&r->lk);
	r->ref--;
	if(r->ref){
		qunlock(&r->lk);
		return;
	}
	assert(r->ref == 0);
	qunlock(&r->lk);
	if(r->parent)
		sourceClose(r->parent);
	memset(r, ~0, sizeof(*r));
	vtfree(r);
}

/*
 * Retrieve the block containing the entry for r.
 * If a snapshot has happened, we might need
 * to get a new copy of the block.  We avoid this
 * in the common case by caching the score for
 * the block and the last epoch in which it was valid.
 *
 * We use r->mode to tell the difference between active
 * file system sources (OReadWrite) and sources for the
 * snapshot file system (OReadOnly).
 */
static Block*
sourceLoadBlock(Source *r, int mode)
{
	u32int addr;
	Block *b;
	char e[ERRMAX];

	switch(r->mode){
	default:
		assert(0);
	case OReadWrite:
		assert(r->mode == OReadWrite);
		/*
		 * This needn't be true -- we might bump the low epoch
		 * to reclaim some old blocks, but since this score is
		 * OReadWrite, the blocks must all still be open, so none
		 * are reclaimed.  Thus it's okay that the epoch is so low.
		 * Proceed.
		assert(r->epoch >= r->fs->elo);
		 */
		if(r->epoch == r->fs->ehi){
			b = cacheGlobal(r->fs->cache, r->score, BtDir, r->tag, OReadWrite);
			if(b == nil)
				return nil;
			assert(r->epoch == b->l.epoch);
			return b;
		}
		assert(r->parent != nil);
		if(!sourceLock(r->parent, OReadWrite))
			return nil;
		b = sourceBlock(r->parent, r->offset/r->epb, OReadWrite);
		sourceUnlock(r->parent);
		if(b == nil)
			return nil;
		assert(b->l.epoch == r->fs->ehi);
	//	fprint(2, "sourceLoadBlock %p %V => %V\n", r, r->score, b->score);
		memmove(r->score, b->score, VtScoreSize);
		r->scoreEpoch = b->l.epoch;
		r->tag = b->l.tag;
		r->epoch = r->fs->ehi;
		return b;

	case OReadOnly:
		addr = globalToLocal(r->score);
		if(addr == NilBlock)
			return cacheGlobal(r->fs->cache, r->score, BtDir, r->tag, mode);

		b = cacheLocalData(r->fs->cache, addr, BtDir, r->tag, mode, r->scoreEpoch);
		if(b)
			return b;

		/*
		 * If it failed because the epochs don't match, the block has been
		 * archived and reclaimed.  Rewalk from the parent and get the
		 * new pointer.  This can't happen in the OReadWrite case
		 * above because blocks in the current epoch don't get
		 * reclaimed.  The fact that we're OReadOnly means we're
		 * a snapshot.  (Or else the file system is read-only, but then
		 * the archiver isn't going around deleting blocks.)
		 */
		rerrstr(e, sizeof e);
		if(strcmp(e, ELabelMismatch) == 0){
			if(!sourceLock(r->parent, OReadOnly))
				return nil;
			b = sourceBlock(r->parent, r->offset/r->epb, OReadOnly);
			sourceUnlock(r->parent);
			if(b){
				fprint(2, "sourceAlloc: lost %V found %V\n",
					r->score, b->score);
				memmove(r->score, b->score, VtScoreSize);
				r->scoreEpoch = b->l.epoch;
				return b;
			}
		}
		return nil;
	}
}

int
sourceLock(Source *r, int mode)
{
	Block *b;

	if(mode == -1)
		mode = r->mode;

	b = sourceLoadBlock(r, mode);
	if(b == nil)
		return 0;
	/*
	 * The fact that we are holding b serves as the
	 * lock entitling us to write to r->b.
	 */
	assert(r->b == nil);
	r->b = b;
	if(r->mode == OReadWrite)
		assert(r->epoch == r->b->l.epoch);
	return 1;
}

/*
 * Lock two (usually sibling) sources.  This needs special care
 * because the Entries for both sources might be in the same block.
 * We also try to lock blocks in left-to-right order within the tree.
 */
int
sourceLock2(Source *r, Source *rr, int mode)
{
	Block *b, *bb;

	if(rr == nil)
		return sourceLock(r, mode);

	if(mode == -1)
		mode = r->mode;

	if(r->parent==rr->parent && r->offset/r->epb == rr->offset/rr->epb){
		b = sourceLoadBlock(r, mode);
		if(b == nil)
			return 0;
		if(memcmp(r->score, rr->score, VtScoreSize) != 0){
			memmove(rr->score, b->score, VtScoreSize);
			rr->scoreEpoch = b->l.epoch;
			rr->tag = b->l.tag;
			rr->epoch = rr->fs->ehi;
		}
		blockDupLock(b);
		bb = b;
	}else if(r->parent==rr->parent || r->offset > rr->offset){
		bb = sourceLoadBlock(rr, mode);
		b = sourceLoadBlock(r, mode);
	}else{
		b = sourceLoadBlock(r, mode);
		bb = sourceLoadBlock(rr, mode);
	}
	if(b == nil || bb == nil){
		if(b)
			blockPut(b);
		if(bb)
			blockPut(bb);
		return 0;
	}

	/*
	 * The fact that we are holding b and bb serves
	 * as the lock entitling us to write to r->b and rr->b.
	 */
	r->b = b;
	rr->b = bb;
	return 1;
}

void
sourceUnlock(Source *r)
{
	Block *b;

	if(r->b == nil){
		fprint(2, "sourceUnlock: already unlocked\n");
		abort();
	}
	b = r->b;
	r->b = nil;
	blockPut(b);
}

static Block*
sourceLoad(Source *r, Entry *e)
{
	Block *b;

	assert(sourceIsLocked(r));
	b = r->b;
	if(!entryUnpack(e, b->data, r->offset % r->epb))
		return nil;
	if(e->gen != r->gen){
		werrstr(ERemoved);
		return nil;
	}
	blockDupLock(b);
	return b;
}

static int
sizeToDepth(uvlong s, int psize, int dsize)
{
	int np;
	int d;

	/* determine pointer depth */
	np = psize/VtScoreSize;
	s = (s + dsize - 1)/dsize;
	for(d = 0; s > 1; d++)
		s = (s + np - 1)/np;
	return d;
}

static u32int
tagGen(void)
{
	u32int tag;

	for(;;){
		tag = lrand();
		if(tag >= UserTag)
			break;
	}
	return tag;
}

char *
sourceName(Source *s)
{
	return fileName(s->file);
}
