Esempio n. 1
0
File: ileaf.c Progetto: Zkin/tux3
/*
 * Chop inums
 * return value:
 * < 0 - error
 *   1 - modified
 *   0 - not modified
 */
static int ileaf_chop(struct btree *btree, tuxkey_t start, u64 len, void *leaf)
{
	struct ileaf *ileaf = leaf;
	__be16 *dict = ileaf_dict(btree, leaf);
	tuxkey_t base = ibase(ileaf);
	unsigned count = icount(ileaf);
	tuxkey_t at = start - base;
	void *startp, *endp, *tailp;
	unsigned size;

	if (at + 1 > count)
		return 0;

	len = min_t(u64, len, count - at);

	startp = ileaf->table + atdict(dict, at);
	endp = ileaf->table + atdict(dict, at + len);
	if (startp == endp)
		return 0;

	/* Remove data */
	tailp = ileaf->table + atdict(dict, count);
	memmove(startp, endp, tailp - endp);

	/* Adjust dict */
	size = endp - startp;
	while (at < count) {
		at++;
		add_idict(dict - at, -size);
	}

	ileaf_trim(btree, leaf);

	return 1;
}
Esempio n. 2
0
File: ileaf.c Progetto: Zkin/tux3
static tuxkey_t ileaf_split(struct btree *btree, tuxkey_t hint,
			    void *from, void *into)
{
	assert(ileaf_sniff(btree, from));
	struct ileaf *leaf = from, *dest = into;
	__be16 *dict = ileaf_dict(btree, from);
	__be16 *destdict = ileaf_dict(btree, into);

#ifdef SPLIT_AT_INUM
	/*
	 * This is to prevent to have same ibase on both of from and into
	 * FIXME: we would want to split at better position.
	 */
	if (hint == ibase(leaf))
		hint++;

	trace("split at inum 0x%Lx", hint);
	unsigned at = min_t(tuxkey_t, hint - ibase(leaf), icount(leaf));
#else
	/* binsearch inum starting nearest middle of block */
	unsigned at = 1, hi = icount(leaf);
	while (at < hi) {
		int mid = (at + hi) / 2;
		if (*(dict - mid) < (btree->sb->blocksize / 2))
			at = mid + 1;
		else
			hi = mid;
	}
#endif
	/* should trim leading empty inodes on copy */
	unsigned split = atdict(dict, at), free = atdict(dict, icount(leaf));
	trace("split at %x of %x", at, icount(leaf));
	trace("copy out %x bytes at %x", free - split, split);
	assert(free >= split);
	memcpy(dest->table, leaf->table + split, free - split);
	dest->count = cpu_to_be16(icount(leaf) - at);
	veccopy(destdict - icount(dest), dict - icount(leaf), icount(dest));
	for (int i = 1; i <= icount(dest); i++)
		add_idict(destdict - i, -split);
#ifdef SPLIT_AT_INUM
	/* round down to multiple of 64 above ibase */
	inum_t round = hint & ~(inum_t)(btree->entries_per_leaf - 1);
	dest->ibase = cpu_to_be64(round > ibase(leaf) + icount(leaf) ? round : hint);
#else
	dest->ibase = cpu_to_be64(ibase(leaf) + at);
#endif
	leaf->count = cpu_to_be16(at);
	memset(leaf->table + split, 0, (char *)(dict - icount(leaf)) - (leaf->table + split));
	ileaf_trim(btree, leaf);
	return ibase(dest);
}
Esempio n. 3
0
int ileaf_purge(struct btree *btree, inum_t inum, struct ileaf *leaf)
{
	if (inum < ibase(leaf) || inum - ibase(leaf) >= btree->entries_per_leaf)
		return -EINVAL;
	be_u16 *dict = (void *)leaf + btree->sb->blocksize;
	unsigned at = inum - ibase(leaf);
	unsigned offset = atdict(dict, at);
	unsigned size = from_be_u16(*(dict - at - 1)) - offset;
	printf("delete inode %Lx from %p[%x/%x]\n", (L)inum, leaf, at, size);
	if (!size)
		return -ENOENT;
	unsigned free = from_be_u16(*(dict - icount(leaf))), tail = free - offset - size;
	assert(offset + size + tail <= free);
	memmove(leaf->table + offset, leaf->table + offset + size, tail);
	for (int i = at + 1; i <= icount(leaf); i++)
		add_idict(dict - i, -size);
	ileaf_trim(btree, leaf);
	return 0;
}
Esempio n. 4
0
static tuxkey_t ileaf_split(struct btree *btree, tuxkey_t inum, vleaf *from, vleaf *into)
{
	assert(ileaf_sniff(btree, from));
	struct ileaf *leaf = from, *dest = into;
	be_u16 *dict = from + btree->sb->blocksize, *destdict = into + btree->sb->blocksize;

#ifdef SPLIT_AT_INUM
	printf("split at inum 0x%Lx\n", (L)inum);
	assert(inum >= ibase(leaf));
	unsigned at = inum - ibase(leaf) < icount(leaf) ? inum - ibase(leaf) : icount(leaf);
#else
	/* binsearch inum starting nearest middle of block */
	unsigned at = 1, hi = icount(leaf);
	while (at < hi) {
		int mid = (at + hi) / 2;
		if (*(dict - mid) < (btree->sb->blocksize / 2))
			at = mid + 1;
		else
			hi = mid;
	}
#endif
	/* should trim leading empty inodes on copy */
	unsigned split = atdict(dict, at), free = from_be_u16(*(dict - icount(leaf)));
	printf("split at %x of %x\n", at, icount(leaf));
	printf("copy out %x bytes at %x\n", free - split, split);
	assert(free >= split);
	memcpy(dest->table, leaf->table + split, free - split);
	dest->count = to_be_u16(icount(leaf) - at);
	veccopy(destdict - icount(dest), dict - icount(leaf), icount(dest));
	for (int i = 1; i <= icount(dest); i++)
		add_idict(destdict - i, -split);
#ifdef SPLIT_AT_INUM
	/* round down to multiple of 64 above ibase */
	inum_t round = inum & ~(inum_t)(btree->entries_per_leaf - 1);
	dest->ibase = to_be_u64(round > ibase(leaf) + icount(leaf) ? round : inum);
#else
	dest->ibase = to_be_u64(ibase(leaf) + at);
#endif
	leaf->count = to_be_u16(at);
	memset(leaf->table + split, 0, (char *)(dict - icount(leaf)) - (leaf->table + split));
	ileaf_trim(btree, leaf);
	return ibase(dest);
}