/*
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
 *
 * This file is part of LVM2.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "lib.h"
#include "btree.h"

struct node {
	uint32_t key;
	struct node *l, *r, *p;

	void *data;
};

struct btree {
	struct dm_pool *mem;
	struct node *root;
};

struct btree *btree_create(struct dm_pool *mem)
{
	struct btree *t = dm_pool_alloc(mem, sizeof(*t));

	if (t) {
		t->mem = mem;
		t->root = NULL;
	}

	return t;
}

/*
 * Shuffle the bits in a key, to try and remove
 * any ordering.
 */
static uint32_t _shuffle(uint32_t k)
{
#if 1
	return ((k & 0xff) << 24 |
		(k & 0xff00) << 8 |
		(k & 0xff0000) >> 8 | (k & 0xff000000) >> 24);
#else
	return k;
#endif
}

static struct node *const *_lookup(struct node *const *c, uint32_t key,
			     struct node **p)
{
	*p = NULL;
	while (*c) {
		*p = *c;
		if ((*c)->key == key)
			break;

		if (key < (*c)->key)
			c = &(*c)->l;

		else
			c = &(*c)->r;
	}

	return c;
}

void *btree_lookup(const struct btree *t, uint32_t k)
{
	uint32_t key = _shuffle(k);
	struct node *p, *const *c = _lookup(&t->root, key, &p);
	return (*c) ? (*c)->data : NULL;
}

int btree_insert(struct btree *t, uint32_t k, void *data)
{
	uint32_t key = _shuffle(k);
	struct node *p, **c = (struct node **) _lookup(&t->root, key, &p), *n;

	if (!*c) {
		if (!(n = dm_pool_alloc(t->mem, sizeof(*n))))
			return_0;

		n->key = key;
		n->data = data;
		n->l = n->r = NULL;
		n->p = p;

		*c = n;
	}

	return 1;
}

void *btree_get_data(const struct btree_iter *it)
{
	return ((const struct node *) it)->data;
}

static struct node *_left(struct node *n)
{
	while (n->l)
		n = n->l;
	return n;
}

struct btree_iter *btree_first(const struct btree *t)
{
	if (!t->root)
		return NULL;

	return (struct btree_iter *) _left(t->root);
}

struct btree_iter *btree_next(const struct btree_iter *it)
{
	struct node *n = (struct node *) it;
	uint32_t k = n->key;

	if (n->r)
		return (struct btree_iter *) _left(n->r);

	do
		n = n->p;
	while (n && k > n->key);

	return (struct btree_iter *) n;
}
