// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */
#include <stdint.h>
#include <stdio.h>
#include "platform_defs.h"
#include "avl64.h"

#define CERT	ASSERT

#ifdef AVL_DEBUG

static void
avl64_checknode(
	avl64tree_desc_t *tree,
	avl64node_t *np)
{
	avl64node_t *back = np->avl_back;
	avl64node_t *forw = np->avl_forw;
	avl64node_t *nextino = np->avl_nextino;
	int bal = np->avl_balance;

	ASSERT(bal != AVL_BALANCE || (!back && !forw) || (back && forw));
	ASSERT(bal != AVL_FORW || forw);
	ASSERT(bal != AVL_BACK || back);

	if (forw) {
		ASSERT(AVL_START(tree, np) < AVL_START(tree, forw));
		ASSERT(np->avl_forw->avl_parent == np);
		ASSERT(back || bal == AVL_FORW);
	} else {
		ASSERT(bal != AVL_FORW);
		ASSERT(bal == AVL_BALANCE || back);
		ASSERT(bal == AVL_BACK || !back);
	}

	if (back) {
		ASSERT(AVL_START(tree, np) > AVL_START(tree, back));
		ASSERT(np->avl_back->avl_parent == np);
		ASSERT(forw || bal == AVL_BACK);
	} else {
		ASSERT(bal != AVL_BACK);
		ASSERT(bal == AVL_BALANCE || forw);
		ASSERT(bal == AVL_FORW || !forw);
	}

	if (nextino == NULL)
		ASSERT(forw == NULL);
	else
		ASSERT(AVL_END(tree, np) <= AVL_START(tree, nextino));
}

static void
avl64_checktree(
	avl64tree_desc_t *tree,
	avl64node_t *root)
{
	avl64node_t *nlast, *nnext, *np;
	uint64_t offset = 0;
	uint64_t end;

	nlast = nnext = root;

	ASSERT(!nnext || nnext->avl_parent == NULL);

	while (nnext) {

		avl64_checknode(tree, nnext);
		end = AVL_END(tree, nnext);

		if (end <= offset) {
			if ((np = nnext->avl_forw) && np != nlast) {
				nlast = nnext;
				nnext = np;
			} else {
				nlast = nnext;
				nnext = nnext->avl_parent;
			}
			continue;
		}

		nlast = nnext;
		if (np = nnext->avl_back) {
			if (AVL_END(tree, np) > offset) {
				nnext = np;
				continue;
			}
		}

		np = nnext;
		nnext = nnext->avl_forw;
		if (!nnext)
			nnext = np->avl_parent;

		offset = end;
	}
}
#else	/* ! AVL_DEBUG */
#define avl64_checktree(t,x)
#endif	/* AVL_DEBUG */


/*
 * Reset balance for np up through tree.
 * ``direction'' is the way that np's balance
 * is headed after the deletion of one of its children --
 * e.g., deleting a avl_forw child sends avl_balance toward AVL_BACK.
 * Called only when deleting a node from the tree.
 */
static void
retreat(
	avl64tree_desc_t *tree,
	avl64node_t *np,
	int direction)
{
	avl64node_t **rootp = &tree->avl_root;
	avl64node_t *parent;
	avl64node_t *child;
	avl64node_t *tmp;
	int	bal;

	do {
		ASSERT(direction == AVL_BACK || direction == AVL_FORW);

		if (np->avl_balance == AVL_BALANCE) {
			np->avl_balance = direction;
			return;
		}

		parent = np->avl_parent;

		/*
		 * If balance is being restored, no local node
		 * reorganization is necessary, but may be at
		 * a higher node.  Reset direction and continue.
		 */
		if (direction != np->avl_balance) {
			np->avl_balance = AVL_BALANCE;
			if (parent) {
				if (parent->avl_forw == np)
					direction = AVL_BACK;
				else
					direction = AVL_FORW;

				np = parent;
				continue;
			}
			return;
		}

		/*
		 * Imbalance.  If a avl_forw node was removed, direction
		 * (and, by reduction, np->avl_balance) is/was AVL_BACK.
		 */
		if (np->avl_balance == AVL_BACK) {

			ASSERT(direction == AVL_BACK);
			child = np->avl_back;
			bal = child->avl_balance;

			if (bal != AVL_FORW) /* single LL */ {
				/*
				 * np gets pushed down to lesser child's
				 * avl_forw branch.
				 *
				 *  np->    -D		    +B
				 *	    / \		    / \
				 * child-> B   deleted	   A  -D
				 *	  / \		      /
				 *	 A   C		     C
				cmn_err(CE_CONT, "!LL delete b 0x%x c 0x%x\n",
					np, child);
				 */

				np->avl_back = child->avl_forw;
				if (child->avl_forw)
					child->avl_forw->avl_parent = np;
				child->avl_forw = np;

				if (parent) {
					if (parent->avl_forw == np) {
						parent->avl_forw = child;
						direction = AVL_BACK;
					} else {
						ASSERT(parent->avl_back == np);
						parent->avl_back = child;
						direction = AVL_FORW;
					}
				} else {
					ASSERT(*rootp == np);
					*rootp = child;
				}
				np->avl_parent = child;
				child->avl_parent = parent;

				if (bal == AVL_BALANCE) {
					np->avl_balance = AVL_BACK;
					child->avl_balance = AVL_FORW;
					return;
				} else {
					np->avl_balance = AVL_BALANCE;
					child->avl_balance = AVL_BALANCE;
					np = parent;
					avl64_checktree(tree, *rootp);
					continue;
				}
			}

			/* child->avl_balance == AVL_FORW  double LR rotation
			 *
			 * child's avl_forw node gets promoted up, along with
			 * its avl_forw subtree
			 *
			 *  np->     -G			  C
			 *	     / \		 / \
			 * child-> +B   H	       -B   G
			 *	   / \   \	       /   / \
			 *	  A  +C   deleted     A   D   H
			 *	       \
			 *	        D
			cmn_err(CE_CONT, "!LR delete b 0x%x c 0x%x t 0x%x\n",
				np, child, child->avl_forw);
			 */

			tmp = child->avl_forw;
			bal = tmp->avl_balance;

			child->avl_forw = tmp->avl_back;
			if (tmp->avl_back)
				tmp->avl_back->avl_parent = child;

			tmp->avl_back = child;
			child->avl_parent = tmp;

			np->avl_back = tmp->avl_forw;
			if (tmp->avl_forw)
				tmp->avl_forw->avl_parent = np;
			tmp->avl_forw = np;

			if (bal == AVL_FORW)
				child->avl_balance = AVL_BACK;
			else
				child->avl_balance = AVL_BALANCE;

			if (bal == AVL_BACK)
				np->avl_balance = AVL_FORW;
			else
				np->avl_balance = AVL_BALANCE;

			goto next;
		}

		ASSERT(np->avl_balance == AVL_FORW && direction == AVL_FORW);

		child = np->avl_forw;
		bal = child->avl_balance;

		if (bal != AVL_BACK) /* single RR */ {
			/*
			 * np gets pushed down to greater child's
			 * avl_back branch.
			 *
			 *  np->    +B		     -D
			 *	    / \		     / \
			 *   deleted   D <-child   +B   E
			 *	      / \	     \
			 *	     C   E	      C
			cmn_err(CE_CONT, "!RR delete b 0x%x c 0x%x\n",
				np, child);
			 */

			np->avl_forw = child->avl_back;
			if (child->avl_back)
				child->avl_back->avl_parent = np;
			child->avl_back = np;

			if (parent) {
				if (parent->avl_forw == np) {
					parent->avl_forw = child;
					direction = AVL_BACK;
				} else {
					ASSERT(parent->avl_back == np);
					parent->avl_back = child;
					direction = AVL_FORW;
				}
			} else {
				ASSERT(*rootp == np);
				*rootp = child;
			}
			np->avl_parent = child;
			child->avl_parent = parent;

			if (bal == AVL_BALANCE) {
				np->avl_balance = AVL_FORW;
				child->avl_balance = AVL_BACK;
				return;
			} else {
				np->avl_balance = AVL_BALANCE;
				child->avl_balance = AVL_BALANCE;
				np = parent;
				avl64_checktree(tree, *rootp);
				continue;
			}
		}

		/* child->avl_balance == AVL_BACK  double RL rotation
		cmn_err(CE_CONT, "!RL delete b 0x%x c 0x%x t 0x%x\n",
			np, child, child->avl_back);
		*/

		tmp = child->avl_back;
		bal = tmp->avl_balance;

		child->avl_back = tmp->avl_forw;
		if (tmp->avl_forw)
			tmp->avl_forw->avl_parent = child;

		tmp->avl_forw = child;
		child->avl_parent = tmp;

		np->avl_forw = tmp->avl_back;
		if (tmp->avl_back)
			tmp->avl_back->avl_parent = np;
		tmp->avl_back = np;

		if (bal == AVL_BACK)
			child->avl_balance = AVL_FORW;
		else
			child->avl_balance = AVL_BALANCE;

		if (bal == AVL_FORW)
			np->avl_balance = AVL_BACK;
		else
			np->avl_balance = AVL_BALANCE;
next:
		np->avl_parent = tmp;
		tmp->avl_balance = AVL_BALANCE;
		tmp->avl_parent = parent;

		if (parent) {
			if (parent->avl_forw == np) {
				parent->avl_forw = tmp;
				direction = AVL_BACK;
			} else {
				ASSERT(parent->avl_back == np);
				parent->avl_back = tmp;
				direction = AVL_FORW;
			}
		} else {
			ASSERT(*rootp == np);
			*rootp = tmp;
			return;
		}

		np = parent;
		avl64_checktree(tree, *rootp);
	} while (np);
}

/*
 *	Remove node from tree.
 *	avl_delete does the local tree manipulations,
 *	calls retreat() to rebalance tree up to its root.
 */
void
avl64_delete(
	avl64tree_desc_t *tree,
	avl64node_t *np)
{
	avl64node_t *forw = np->avl_forw;
	avl64node_t *back = np->avl_back;
	avl64node_t *parent = np->avl_parent;
	avl64node_t *nnext;


	if (np->avl_back) {
		/*
		 * a left child exits, then greatest left descendent's nextino
		 * is pointing to np; make it point to np->nextino.
		 */
		nnext = np->avl_back;
		while (nnext) {
			if (!nnext->avl_forw)
				break; /* can't find anything bigger */
			nnext = nnext->avl_forw;
		}
	} else
	if (np->avl_parent) {
		/*
		 * find nearest ancestor with lesser value. That ancestor's
		 * nextino is pointing to np; make it point to np->nextino
		 */
		 nnext = np->avl_parent;
		 while (nnext) {
			if (AVL_END(tree, nnext) <= AVL_END(tree, np))
				break;
			nnext = nnext->avl_parent;
		}
	} else
		nnext = NULL;

	if (nnext) {
		ASSERT(nnext->avl_nextino == np);
		nnext->avl_nextino = np->avl_nextino;
		/*
		 *	Something preceeds np; np cannot be firstino.
		 */
		ASSERT(tree->avl_firstino != np);
	}
	else {
		/*
		 *	Nothing preceeding np; after deletion, np's nextino
		 *	is firstino of tree.
		 */
		ASSERT(tree->avl_firstino == np);
		tree->avl_firstino = np->avl_nextino;
	}


	/*
	 * Degenerate cases...
	 */
	if (forw == NULL) {
		forw = back;
		goto attach;
	}

	if (back == NULL) {
attach:
		if (forw)
			forw->avl_parent = parent;
		if (parent) {
			if (parent->avl_forw == np) {
				parent->avl_forw = forw;
				retreat(tree, parent, AVL_BACK);
			} else {
				ASSERT(parent->avl_back == np);
				parent->avl_back = forw;
				retreat(tree, parent, AVL_FORW);
			}
		} else {
			ASSERT(tree->avl_root == np);
			tree->avl_root = forw;
		}
		avl64_checktree(tree, tree->avl_root);
		return;
	}

	/*
	 * Harder case: children on both sides.
	 * If back's avl_forw pointer is null, just have back
	 * inherit np's avl_forw tree, remove np from the tree
	 * and adjust balance counters starting at back.
	 *
	 * np->	    xI		    xH	(befor retreat())
	 *	    / \		    / \
	 * back->  H   J	   G   J
	 *	  /   / \             / \
	 *       G   ?   ?           ?   ?
	 *      / \
	 *     ?   ?
	 */
	if ((forw = back->avl_forw) == NULL) {
		/*
		 * AVL_FORW retreat below will set back's
		 * balance to AVL_BACK.
		 */
		back->avl_balance = np->avl_balance;
		back->avl_forw = forw = np->avl_forw;
		forw->avl_parent = back;
		back->avl_parent = parent;

		if (parent) {
			if (parent->avl_forw == np)
				parent->avl_forw = back;
			else {
				ASSERT(parent->avl_back == np);
				parent->avl_back = back;
			}
		} else {
			ASSERT(tree->avl_root == np);
			tree->avl_root = back;
		}

		/*
		 * back is taking np's place in the tree, and
		 * has therefore lost a avl_back node (itself).
		 */
		retreat(tree, back, AVL_FORW);
		avl64_checktree(tree, tree->avl_root);
		return;
	}

	/*
	 * Hardest case: children on both sides, and back's
	 * avl_forw pointer isn't null.  Find the immediately
	 * inferior buffer by following back's avl_forw line
	 * to the end, then have it inherit np's avl_forw tree.
	 *
	 * np->	    xI			      xH
	 *	    / \			      / \
	 *         G   J	     back->  G   J   (before retreat())
	 *	  / \			    / \
	 *       F   ?...		   F   ?1
	 *      /     \
	 *     ?       H  <-forw
	 *	      /
	 *	     ?1
	 */
	while ((back = forw->avl_forw))
		forw = back;

	/*
	 * Will be adjusted by retreat() below.
	 */
	forw->avl_balance = np->avl_balance;

	/*
	 * forw inherits np's avl_forw...
	 */
	forw->avl_forw = np->avl_forw;
	np->avl_forw->avl_parent = forw;

	/*
	 * ... forw's parent gets forw's avl_back...
	 */
	back = forw->avl_parent;
	back->avl_forw = forw->avl_back;
	if (forw->avl_back)
		forw->avl_back->avl_parent = back;

	/*
	 * ... forw gets np's avl_back...
	 */
	forw->avl_back = np->avl_back;
	np->avl_back->avl_parent = forw;

	/*
	 * ... and forw gets np's parent.
	 */
	forw->avl_parent = parent;

	if (parent) {
		if (parent->avl_forw == np)
			parent->avl_forw = forw;
		else
			parent->avl_back = forw;
	} else {
		ASSERT(tree->avl_root == np);
		tree->avl_root = forw;
	}

	/*
	 * What used to be forw's parent is the starting
	 * point for rebalancing.  It has lost a avl_forw node.
	 */
	retreat(tree, back, AVL_BACK);
	avl64_checktree(tree, tree->avl_root);
}


/*
 *	avl_findanyrange:
 *
 *	Given range r [start, end), find any range which is contained in r.
 *	if checklen is non-zero, then only ranges of non-zero length are
 *	considered in finding a match.
 */
avl64node_t *
avl64_findanyrange(
	avl64tree_desc_t *tree,
	uint64_t start,
	uint64_t end,
	int	checklen)
{
	avl64node_t *np = tree->avl_root;

	/* np = avl64_findadjacent(tree, start, AVL_SUCCEED); */
	while (np) {
		if (start < AVL_START(tree, np)) {
			if (np->avl_back) {
				np = np->avl_back;
				continue;
			}
			/* if we were to add node with start, would
			 * have a growth of AVL_BACK
			 */
			/* if succeeding node is needed, this is it.
			 */
			break;
		}
		if (start >= AVL_END(tree, np)) {
			if (np->avl_forw) {
				np = np->avl_forw;
				continue;
			}
			/* if we were to add node with start, would
			 * have a growth of AVL_FORW;
			 */
			/* we are looking for a succeeding node;
			 * this is nextino.
			 */
			np = np->avl_nextino;
			break;
		}
		/* AVL_START(tree, np) <= start < AVL_END(tree, np) */
		break;
	}
	if (np) {
		if (checklen == AVL_INCLUDE_ZEROLEN) {
			if (end <= AVL_START(tree, np)) {
				/* something follows start, but is
				 * is entierly after the range (end)
				 */
				return(NULL);
			}
			/* np may stradle [start, end) */
			return(np);
		}
		/*
		 * find non-zero length region
		 */
		while (np && (AVL_END(tree, np) - AVL_START(tree, np) == 0)
			&& (AVL_START(tree, np)  < end))
				np = np->avl_nextino;

		if ((np == NULL) || (AVL_START(tree, np) >= end))
			return NULL;
		return(np);
	}
	/*
	 * nothing succeeds start, all existing ranges are before start.
	 */
	return NULL;
}


/*
 * Returns a pointer to range which contains value.
 */
avl64node_t *
avl64_findrange(
	avl64tree_desc_t *tree,
	uint64_t value)
{
	avl64node_t *np = tree->avl_root;

	while (np) {
		if (value < AVL_START(tree, np)) {
			np = np->avl_back;
			continue;
		}
		if (value >= AVL_END(tree, np)) {
			np = np->avl_forw;
			continue;
		}
		ASSERT(AVL_START(tree, np) <= value &&
		       value < AVL_END(tree, np));
		return np;
	}
	return NULL;
}


/*
 * Returns a pointer to node which contains exact value.
 */
avl64node_t *
avl64_find(
	avl64tree_desc_t *tree,
	uint64_t value)
{
	avl64node_t *np = tree->avl_root;
	uint64_t nvalue;

	while (np) {
		nvalue = AVL_START(tree, np);
		if (value < nvalue) {
			np = np->avl_back;
			continue;
		}
		if (value == nvalue) {
			return np;
		}
		np = np->avl_forw;
	}
	return NULL;
}


/*
 * Balance buffer AVL tree after attaching a new node to root.
 * Called only by avl_insert.
 */
static void
avl64_balance(
	avl64node_t **rootp,
	avl64node_t *np,
	int growth)
{
	/*
	 * At this point, np points to the node to which
	 * a new node has been attached.  All that remains is to
	 * propagate avl_balance up the tree.
	 */
	for ( ; ; ) {
		avl64node_t *parent = np->avl_parent;
		avl64node_t *child;

		CERT(growth == AVL_BACK || growth == AVL_FORW);

		/*
		 * If the buffer was already balanced, set avl_balance
		 * to the new direction.  Continue if there is a
		 * parent after setting growth to reflect np's
		 * relation to its parent.
		 */
		if (np->avl_balance == AVL_BALANCE) {
			np->avl_balance = growth;
			if (parent) {
				if (parent->avl_forw == np)
					growth = AVL_FORW;
				else {
					ASSERT(parent->avl_back == np);
					growth = AVL_BACK;
				}

				np = parent;
				continue;
			}
			break;
		}

		if (growth != np->avl_balance) {
			/*
			 * Subtree is now balanced -- no net effect
			 * in the size of the subtree, so leave.
			 */
			np->avl_balance = AVL_BALANCE;
			break;
		}

		if (growth == AVL_BACK) {

			child = np->avl_back;
			CERT(np->avl_balance == AVL_BACK && child);

			if (child->avl_balance == AVL_BACK) { /* single LL */
				/*
				 * ``A'' just got inserted;
				 * np points to ``E'', child to ``C'',
				 * and it is already AVL_BACK --
				 * child will get promoted to top of subtree.

				np->	     -E			C
					     / \	       / \
				child->	   -C   F	     -B   E
					   / \		     /   / \
					 -B   D		    A   D   F
					 /
					A

					Note that child->avl_parent and
					avl_balance get set in common code.
				 */
				np->avl_parent = child;
				np->avl_balance = AVL_BALANCE;
				np->avl_back = child->avl_forw;
				if (child->avl_forw)
					child->avl_forw->avl_parent = np;
				child->avl_forw = np;
			} else {
				/*
				 * double LR
				 *
				 * child's avl_forw node gets promoted to
				 * the top of the subtree.

				np->	     -E		      C
					     / \	     / \
				child->	   +B   F	   -B   E
					   / \		   /   / \
					  A  +C		  A   D   F
					       \
						D

				 */
				avl64node_t *tmp = child->avl_forw;

				CERT(child->avl_balance == AVL_FORW && tmp);

				child->avl_forw = tmp->avl_back;
				if (tmp->avl_back)
					tmp->avl_back->avl_parent = child;

				tmp->avl_back = child;
				child->avl_parent = tmp;

				np->avl_back = tmp->avl_forw;
				if (tmp->avl_forw)
					tmp->avl_forw->avl_parent = np;

				tmp->avl_forw = np;
				np->avl_parent = tmp;

				if (tmp->avl_balance == AVL_BACK)
					np->avl_balance = AVL_FORW;
				else
					np->avl_balance = AVL_BALANCE;

				if (tmp->avl_balance == AVL_FORW)
					child->avl_balance = AVL_BACK;
				else
					child->avl_balance = AVL_BALANCE;

				/*
				 * Set child to point to tmp since it is
				 * now the top of the subtree, and will
				 * get attached to the subtree parent in
				 * the common code below.
				 */
				child = tmp;
			}

		} else /* growth == AVL_BACK */ {

			/*
			 * This code is the mirror image of AVL_FORW above.
			 */

			child = np->avl_forw;
			CERT(np->avl_balance == AVL_FORW && child);

			if (child->avl_balance == AVL_FORW) { /* single RR */
				np->avl_parent = child;
				np->avl_balance = AVL_BALANCE;
				np->avl_forw = child->avl_back;
				if (child->avl_back)
					child->avl_back->avl_parent = np;
				child->avl_back = np;
			} else {
				/*
				 * double RL
				 */
				avl64node_t *tmp = child->avl_back;

				ASSERT(child->avl_balance == AVL_BACK && tmp);

				child->avl_back = tmp->avl_forw;
				if (tmp->avl_forw)
					tmp->avl_forw->avl_parent = child;

				tmp->avl_forw = child;
				child->avl_parent = tmp;

				np->avl_forw = tmp->avl_back;
				if (tmp->avl_back)
					tmp->avl_back->avl_parent = np;

				tmp->avl_back = np;
				np->avl_parent = tmp;

				if (tmp->avl_balance == AVL_FORW)
					np->avl_balance = AVL_BACK;
				else
					np->avl_balance = AVL_BALANCE;

				if (tmp->avl_balance == AVL_BACK)
					child->avl_balance = AVL_FORW;
				else
					child->avl_balance = AVL_BALANCE;

				child = tmp;
			}
		}

		child->avl_parent = parent;
		child->avl_balance = AVL_BALANCE;

		if (parent) {
			if (parent->avl_back == np)
				parent->avl_back = child;
			else
				parent->avl_forw = child;
		} else {
			ASSERT(*rootp == np);
			*rootp = child;
		}

		break;
	}
}

static
avl64node_t *
avl64_insert_find_growth(
		avl64tree_desc_t *tree,
		uint64_t start,	/* range start at start, */
		uint64_t end,	/* exclusive */
		int   *growthp)	/* OUT */
{
	avl64node_t *root = tree->avl_root;
	avl64node_t *np;

	np = root;
	ASSERT(np); /* caller ensures that there is atleast one node in tree */

	for ( ; ; ) {
		CERT(np->avl_parent || root == np);
		CERT(!np->avl_parent || root != np);
		CERT(!(np->avl_back) || np->avl_back->avl_parent == np);
		CERT(!(np->avl_forw) || np->avl_forw->avl_parent == np);
		CERT(np->avl_balance != AVL_FORW || np->avl_forw);
		CERT(np->avl_balance != AVL_BACK || np->avl_back);
		CERT(np->avl_balance != AVL_BALANCE ||
		     np->avl_back == NULL || np->avl_forw);
		CERT(np->avl_balance != AVL_BALANCE ||
		     np->avl_forw == NULL || np->avl_back);

		if (AVL_START(tree, np) >= end) {
			if (np->avl_back) {
				np = np->avl_back;
				continue;
			}
			*growthp = AVL_BACK;
			break;
		}

		if (AVL_END(tree, np) <= start) {
			if (np->avl_forw) {
				np = np->avl_forw;
				continue;
			}
			*growthp = AVL_FORW;
			break;
		}
		/* found exact match -- let caller decide if it is an error */
		return(NULL);
	}
	return(np);
}


static void
avl64_insert_grow(
	avl64tree_desc_t *tree,
	avl64node_t *parent,
	avl64node_t *newnode,
	int growth)
{
	avl64node_t *nnext;
	uint64_t start = AVL_START(tree, newnode);

	if (growth == AVL_BACK) {

		parent->avl_back = newnode;
		/*
		 * we are growing to the left; previous in-order to newnode is
		 * closest ancestor with lesser value. Before this
		 * insertion, this ancestor will be pointing to
		 * newnode's parent. After insertion, next in-order to newnode
		 * is the parent.
		 */
		newnode->avl_nextino = parent;
		nnext = parent;
		while (nnext) {
			if (AVL_END(tree, nnext) <= start)
				break;
			nnext = nnext->avl_parent;
		}
		if (nnext)  {
			/*
			 * nnext will be null if newnode is
			 * the least element, and hence very first in the list.
			 */
			ASSERT(nnext->avl_nextino == parent);
			nnext->avl_nextino = newnode;
		}
	}
	else {
		parent->avl_forw = newnode;
		newnode->avl_nextino = parent->avl_nextino;
		parent->avl_nextino = newnode;
	}
}


avl64node_t *
avl64_insert(
	avl64tree_desc_t *tree,
	avl64node_t *newnode)
{
	avl64node_t *np;
	uint64_t start = AVL_START(tree, newnode);
	uint64_t end = AVL_END(tree, newnode);
	int growth;

	ASSERT(newnode);
	/*
	 * Clean all pointers for sanity; some will be reset as necessary.
	 */
	newnode->avl_nextino = NULL;
	newnode->avl_parent = NULL;
	newnode->avl_forw = NULL;
	newnode->avl_back = NULL;
	newnode->avl_balance = AVL_BALANCE;

	if ((np = tree->avl_root) == NULL) { /* degenerate case... */
		tree->avl_root = newnode;
		tree->avl_firstino = newnode;
		return newnode;
	}

	if ((np = avl64_insert_find_growth(tree, start, end, &growth))
			== NULL) {
		if (start != end)  { /* non-zero length range */
			fprintf(stderr,
		_("avl_insert: Warning! duplicate range [%llu,%llu]\n"),
				(unsigned long long)start,
				(unsigned long long)end);
		}
		return(NULL);
	}

	avl64_insert_grow(tree, np, newnode, growth);
	if (growth == AVL_BACK) {
		/*
		 * Growing to left. if np was firstino, newnode will be firstino
		 */
		 if (tree->avl_firstino == np)
			tree->avl_firstino = newnode;
	}
#ifdef notneeded
	else
	if (growth == AVL_FORW)
		/*
		 * Cannot possibly be firstino; there is somebody to our left.
		 */
		 ;
#endif

	newnode->avl_parent = np;
	CERT(np->avl_forw == newnode || np->avl_back == newnode);

	avl64_balance(&tree->avl_root, np, growth);

	avl64_checktree(tree, tree->avl_root);

	return newnode;
}

/*
 *
 * avl64_insert_immediate(tree, afterp, newnode):
 *	insert newnode immediately into tree immediately after afterp.
 *	after insertion, newnode is right child of afterp.
 */
void
avl64_insert_immediate(
		avl64tree_desc_t *tree,
		avl64node_t *afterp,
		avl64node_t *newnode)
{
	/*
	 * Clean all pointers for sanity; some will be reset as necessary.
	 */
	newnode->avl_nextino = NULL;
	newnode->avl_parent = NULL;
	newnode->avl_forw = NULL;
	newnode->avl_back = NULL;
	newnode->avl_balance = AVL_BALANCE;

	if (afterp == NULL) {
		tree->avl_root = newnode;
		tree->avl_firstino = newnode;
		return;
	}

	ASSERT(afterp->avl_forw == NULL);
	avl64_insert_grow(tree, afterp, newnode, AVL_FORW); /* grow to right */
	CERT(afterp->avl_forw == newnode);
	avl64_balance(&tree->avl_root, afterp, AVL_FORW);
	avl64_checktree(tree, tree->avl_root);
}


/*
 *	Returns first in order node
 */
avl64node_t *
avl64_firstino(avl64node_t *root)
{
	avl64node_t *np;

	if ((np = root) == NULL)
		return NULL;

	while (np->avl_back)
		np = np->avl_back;
	return np;
}

/*
 *	Returns last in order node
 */
avl64node_t *
avl64_lastino(avl64node_t *root)
{
	avl64node_t *np;

	if ((np = root) == NULL)
		return NULL;

	while (np->avl_forw)
		np = np->avl_forw;
	return np;
}

void
avl64_init_tree(avl64tree_desc_t *tree, avl64ops_t *ops)
{
	tree->avl_root = NULL;
	tree->avl_firstino = NULL;
	tree->avl_ops = ops;
}

#ifdef AVL_DEBUG
static void
avl64_printnode(avl64tree_desc_t *tree, avl64node_t *np, int nl)
{
	printf("[%d-%d]%c", AVL_START(tree, np),
		(AVL_END(tree, np) - 1), nl ? '\n' : ' ');
}
#endif
#ifdef STAND_ALONE_DEBUG

struct avl_debug_node {
	avl64node_t	avl_node;
	xfs_off_t		avl_start;
	unsigned int	avl_size;
}

avl64ops_t avl_debug_ops = {
	avl_debug_start,
	avl_debug_end,
}

static uint64_t
avl64_debug_start(avl64node_t *node)
{
	return (uint64_t)(struct avl_debug_node *)node->avl_start;
}

static uint64_t
avl64_debug_end(avl64node_t *node)
{
	return (uint64_t)
		((struct avl_debug_node *)node->avl_start +
		 (struct avl_debug_node *)node->avl_size);
}

avl_debug_node	freenodes[100];
avl_debug_node	*freehead = &freenodes[0];

static avl64node_t *
alloc_avl64_debug_node()
{
	freehead->avl_balance = AVL_BALANCE;
	freehead->avl_parent = freehead->avl_forw = freehead->avl_back = NULL;
	return(freehead++);
}

static void
avl64_print(avl64tree_desc_t *tree, avl64node_t *root, int depth)
{
	int i;

	if (!root)
		return;
	if (root->avl_forw)
		avl64_print(tree, root->avl_forw, depth+5);
	for (i = 0; i < depth; i++)
		putchar((int) ' ');
	avl64_printnode(tree, root,1);
	if (root->avl_back)
		avl64_print(tree, root->avl_back, depth+5);
}

main()
{
	int		i, j;
	avl64node_t	*np;
	avl64tree_desc_t	tree;
	char		linebuf[256], cmd[256];

	avl64_init_tree(&tree, &avl_debug_ops);

	for (i = 100; i > 0; i = i - 10)
	{
		np = alloc__debug_avlnode();
		ASSERT(np);
		np->avl_start = i;
		np->avl_size = 10;
		avl64_insert(&tree, np);
	}
	avl64_print(&tree, tree.avl_root, 0);

	for (np = tree.avl_firstino; np != NULL; np = np->avl_nextino)
		avl64_printnode(&tree, np, 0);
	printf("\n");

	while (1) {
		printf(_("Command [fpdir] : "));
		fgets(linebuf, 256, stdin);
		if (feof(stdin)) break;
		cmd[0] = NULL;
		if (sscanf(linebuf, "%[fpdir]%d", cmd, &i) != 2)
			continue;
		switch (cmd[0]) {
		case 'd':
		case 'f':
			printf(_("end of range ? "));
			fgets(linebuf, 256, stdin);
			j = atoi(linebuf);

			if (i == j) j = i+1;
			np = avl64_findinrange(&tree,i,j);
			if (np) {
				avl64_printnode(&tree, np, 1);
				if (cmd[0] == 'd')
					avl64_delete(&tree, np);
			} else
				printf(_("Cannot find %d\n"), i);
			break;
		case 'p':
			avl64_print(&tree, tree.avl_root, 0);
			for (np = tree.avl_firstino;
				np != NULL; np = np->avl_nextino)
					avl64_printnode(&tree, np, 0);
			printf("\n");
			break;
		case 'i':
			np = alloc_avlnode();
			ASSERT(np);
			np->avl_start = i;
			printf(_("size of range ? "));
			fgets(linebuf, 256, stdin);
			j = atoi(linebuf);

			np->avl_size = j;
			avl64_insert(&tree, np);
			break;
		case 'r': {
			avl64node_t	*b, *e, *t;
			int		checklen;

			printf(_("End of range ? "));
			fgets(linebuf, 256, stdin);
			j = atoi(linebuf);

			printf(_("checklen 0/1 ? "));
			fgets(linebuf, 256, stdin);
			checklen = atoi(linebuf);


			b = avl64_findanyrange(&tree, i, j, checklen);
			if (b) {
				printf(_("Found something\n"));
				t = b;
				while (t)  {
					if (t != b &&
					    AVL_START(&tree, t) >= j)
						break;
					avl64_printnode(&tree, t, 0);
					t = t->avl_nextino;
				}
				printf("\n");
			}
		     }
		}
	}
}
#endif

/*
 *	Given a tree, find value; will find return range enclosing value,
 *	or range immediately succeeding value,
 *	or range immediately preceeding value.
 */
avl64node_t *
avl64_findadjacent(
	avl64tree_desc_t *tree,
	uint64_t value,
	int		dir)
{
	avl64node_t *np = tree->avl_root;

	while (np) {
		if (value < AVL_START(tree, np)) {
			if (np->avl_back) {
				np = np->avl_back;
				continue;
			}
			/* if we were to add node with value, would
			 * have a growth of AVL_BACK
			 */
			if (dir == AVL_SUCCEED) {
				/* if succeeding node is needed, this is it.
				 */
				return(np);
			}
			if (dir == AVL_PRECEED) {
				/*
				 * find nearest ancestor with lesser value.
				 */
				 np = np->avl_parent;
				 while (np) {
					if (AVL_END(tree, np) <= value)
						break;
					np = np->avl_parent;
				}
				return(np);
			}
			ASSERT(dir == AVL_SUCCEED || dir == AVL_PRECEED);
			break;
		}
		if (value >= AVL_END(tree, np)) {
			if (np->avl_forw) {
				np = np->avl_forw;
				continue;
			}
			/* if we were to add node with value, would
			 * have a growth of AVL_FORW;
			 */
			if (dir == AVL_SUCCEED) {
				/* we are looking for a succeeding node;
				 * this is nextino.
				 */
				return(np->avl_nextino);
			}
			if (dir == AVL_PRECEED) {
				/* looking for a preceeding node; this is it. */
				return(np);
			}
			ASSERT(dir == AVL_SUCCEED || dir == AVL_PRECEED);
		}
		/* AVL_START(tree, np) <= value < AVL_END(tree, np) */
		return(np);
	}
	return NULL;
}


/*
 *	avl_findranges:
 *
 *	Given range r [start, end), find all ranges in tree which are contained
 *	in r. At return, startp and endp point to first and last of
 *	a chain of elements which describe the contained ranges. Elements
 *	in startp ... endp are in sort order, and can be accessed by
 *	using avl_nextino.
 */

void
avl64_findranges(
	avl64tree_desc_t *tree,
	uint64_t start,
	uint64_t end,
	avl64node_t	        **startp,
	avl64node_t		**endp)
{
	avl64node_t *np;

	np = avl64_findadjacent(tree, start, AVL_SUCCEED);
	if (np == NULL				/* nothing succeding start */
		|| (np && (end <= AVL_START(tree, np))))
						/* something follows start,
						but... is entirely after end */
	{
		*startp = NULL;
		*endp = NULL;
		return;
	}

	*startp = np;

	/* see if end is in this region itself */
	if (end <= AVL_END(tree, np) ||
	    np->avl_nextino == NULL ||
	    (np->avl_nextino &&
	    (end <= AVL_START(tree, np->avl_nextino)))) {
		*endp = np;
		return;
	}
	/* have to munge for end */
	/*
	 * note: have to look for (end - 1), since
	 * findadjacent will look for exact value, and does not
	 * care about the fact that end is actually one more
	 * than the value actually being looked for; thus feed it one less.
	 */
	*endp = avl64_findadjacent(tree, (end-1), AVL_PRECEED);
	ASSERT(*endp);
}
