/*
 * Elastic Binary Trees - macros and structures for operations on 32bit nodes.
 * Version 6.0.6 with backports from v7-dev
 * (C) 2002-2017 - Willy Tarreau <w@1wt.eu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _EB32SCTREE_H
#define _EB32SCTREE_H

#include "ebtree.h"


/* Return the structure of type <type> whose member <member> points to <ptr> */
#define eb32sc_entry(ptr, type, member) container_of(ptr, type, member)

/* These types may sometimes already be defined */
#ifndef _EB32TREE_H
typedef unsigned int u32;
typedef   signed int s32;
#endif

/* This structure carries a node, a leaf, a scope, and a key. It must start
 * with the eb_node so that it can be cast into an eb_node. We could also
 * have put some sort of transparent union here to reduce the indirection
 * level, but the fact is, the end user is not meant to manipulate internals,
 * so this is pointless.
 * In case sizeof(void*)>=sizeof(long), we know there will be some padding after
 * the leaf if it's unaligned. In this case we force the alignment on void* so
 * that we prefer to have the padding before for more efficient accesses.
 */
struct eb32sc_node {
	struct eb_node node; /* the tree node, must be at the beginning */
	MAYBE_ALIGN(sizeof(u32));
	u32 key;
	ALWAYS_ALIGN(sizeof(void*));
	unsigned long node_s; /* visibility of this node's branches */
	unsigned long leaf_s; /* visibility of this node's leaf */
} ALIGNED(sizeof(void*));

/*
 * Exported functions and macros.
 * Many of them are always inlined because they are extremely small, and
 * are generally called at most once or twice in a program.
 */

/*
 * The following functions are not inlined by default. They are declared
 * in eb32sctree.c, which simply relies on their inline version.
 */
REGPRM2 struct eb32sc_node *eb32sc_lookup_ge(struct eb_root *root, u32 x, unsigned long scope);
REGPRM2 struct eb32sc_node *eb32sc_lookup_ge_or_first(struct eb_root *root, u32 x, unsigned long scope);
REGPRM2 struct eb32sc_node *eb32sc_insert(struct eb_root *root, struct eb32sc_node *new, unsigned long scope);
void eb32sc_delete(struct eb32sc_node *node);

/* Walks down left starting at root pointer <start>, and follow the leftmost
 * branch whose scope matches <scope>. It either returns the node hosting the
 * first leaf on that side, or NULL if no leaf is found. <start> may either be
 * NULL or a branch pointer. The pointer to the leaf (or NULL) is returned.
 */
static inline struct eb32sc_node *eb32sc_walk_down_left(eb_troot_t *start, unsigned long scope)
{
	struct eb_root *root;
	struct eb_node *node;
	struct eb32sc_node *eb32;

	if (unlikely(!start))
		return NULL;

	while (1) {
		if (eb_gettag(start) == EB_NODE) {
			root = eb_untag(start, EB_NODE);
			node = eb_root_to_node(root);
			eb32 = container_of(node, struct eb32sc_node, node);
			if (eb32->node_s & scope) {
				start = node->branches.b[EB_LEFT];
				continue;
			}
			start = node->node_p;
		}
		else {
			root = eb_untag(start, EB_LEAF);
			node = eb_root_to_node(root);
			eb32 = container_of(node, struct eb32sc_node, node);
			if (eb32->leaf_s & scope)
				return eb32;
			start = node->leaf_p;
		}

		/* here we're on a node that doesn't match the scope. We have
		 * to walk to the closest right location.
		 */
		while (eb_gettag(start) != EB_LEFT)
			/* Walking up from right branch, so we cannot be below root */
			start = (eb_root_to_node(eb_untag(start, EB_RGHT)))->node_p;

		/* Note that <start> cannot be NULL at this stage */
		root = eb_untag(start, EB_LEFT);
		start = root->b[EB_RGHT];
		if (eb_clrtag(start) == NULL)
			return NULL;
	}
}

/* Return next node in the tree, starting with tagged parent <start>, or NULL if none */
static inline struct eb32sc_node *eb32sc_next_with_parent(eb_troot_t *start, unsigned long scope)
{
	while (eb_gettag(start) != EB_LEFT)
		/* Walking up from right branch, so we cannot be below root */
		start = (eb_root_to_node(eb_untag(start, EB_RGHT)))->node_p;

	/* Note that <t> cannot be NULL at this stage */
	start = (eb_untag(start, EB_LEFT))->b[EB_RGHT];
	if (eb_clrtag(start) == NULL)
		return NULL;

	return eb32sc_walk_down_left(start, scope);
}

/* Return next node in the tree, or NULL if none */
static inline struct eb32sc_node *eb32sc_next(struct eb32sc_node *eb32, unsigned long scope)
{
	return eb32sc_next_with_parent(eb32->node.leaf_p, scope);
}

/* Return leftmost node in the tree, or NULL if none */
static inline struct eb32sc_node *eb32sc_first(struct eb_root *root, unsigned long scope)
{
	return eb32sc_walk_down_left(root->b[0], scope);
}

#endif /* _EB32SC_TREE_H */
