/*
 * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

/*
 * Abstract:
 *	Declaration of quick map, a binary tree where the caller always provides
 *	all necessary storage.
 */

#ifndef _CL_QMAP_H_
#define _CL_QMAP_H_

#include <stdbool.h>
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>

typedef struct _cl_list_item {
        struct _cl_list_item *p_next;
        struct _cl_list_item *p_prev;
} cl_list_item_t;

typedef struct _cl_pool_item {
        cl_list_item_t list_item;
} cl_pool_item_t;

/****h* Component Library/Quick Map
* NAME
*	Quick Map
*
* DESCRIPTION
*	Quick map implements a binary tree that stores user provided cl_map_item_t
*	structures.  Each item stored in a quick map has a unique 64-bit key
*	(duplicates are not allowed).  Quick map provides the ability to
*	efficiently search for an item given a key.
*
*	Quick map does not allocate any memory, and can therefore not fail
*	any operations due to insufficient memory.  Quick map can thus be useful
*	in minimizing the error paths in code.
*
*	Quick map is not thread safe, and users must provide serialization when
*	adding and removing items from the map.
*
*	The quick map functions operate on a cl_qmap_t structure which should be
*	treated as opaque and should be manipulated only through the provided
*	functions.
*
* SEE ALSO
*	Structures:
*		cl_qmap_t, cl_map_item_t, cl_map_obj_t
*
*	Callbacks:
*		cl_pfn_qmap_apply_t
*
*	Item Manipulation:
*		cl_qmap_set_obj, cl_qmap_obj, cl_qmap_key
*
*	Initialization:
*		cl_qmap_init
*
*	Iteration:
*		cl_qmap_end, cl_qmap_head, cl_qmap_tail, cl_qmap_next, cl_qmap_prev
*
*	Manipulation:
*		cl_qmap_insert, cl_qmap_get, cl_qmap_remove_item, cl_qmap_remove,
*		cl_qmap_remove_all, cl_qmap_merge, cl_qmap_delta, cl_qmap_get_next
*
*	Search:
*		cl_qmap_apply_func
*
*	Attributes:
*		cl_qmap_count, cl_is_qmap_empty,
*********/
/****i* Component Library: Quick Map/cl_map_color_t
* NAME
*	cl_map_color_t
*
* DESCRIPTION
*	The cl_map_color_t enumerated type is used to note the color of
*	nodes in a map.
*
* SYNOPSIS
*/
typedef enum _cl_map_color {
	CL_MAP_RED,
	CL_MAP_BLACK
} cl_map_color_t;
/*
* VALUES
*	CL_MAP_RED
*		The node in the map is red.
*
*	CL_MAP_BLACK
*		The node in the map is black.
*
* SEE ALSO
*	Quick Map, cl_map_item_t
*********/

/****s* Component Library: Quick Map/cl_map_item_t
* NAME
*	cl_map_item_t
*
* DESCRIPTION
*	The cl_map_item_t structure is used by maps to store objects.
*
*	The cl_map_item_t structure should be treated as opaque and should
*	be manipulated only through the provided functions.
*
* SYNOPSIS
*/
typedef struct _cl_map_item {
	/* Must be first to allow casting. */
	cl_pool_item_t pool_item;
	struct _cl_map_item *p_left;
	struct _cl_map_item *p_right;
	struct _cl_map_item *p_up;
	cl_map_color_t color;
	uint64_t key;
#ifdef _DEBUG_
	struct _cl_qmap *p_map;
#endif
} cl_map_item_t;
/*
* FIELDS
*	pool_item
*		Used to store the item in a doubly linked list, allowing more
*		efficient map traversal.
*
*	p_left
*		Pointer to the map item that is a child to the left of the node.
*
*	p_right
*		Pointer to the map item that is a child to the right of the node.
*
*	p_up
*		Pointer to the map item that is the parent of the node.
*
*	color
*		Indicates whether a node is red or black in the map.
*
*	key
*		Value that uniquely represents a node in a map.  This value is
*		set by calling cl_qmap_insert and can be retrieved by calling
*		cl_qmap_key.
*
* NOTES
*	None of the fields of this structure should be manipulated by users, as
*	they are crititcal to the proper operation of the map in which they
*	are stored.
*
*	To allow storing items in either a quick list, a quick pool, or a quick
*	map, the map implementation guarantees that the map item can be safely
*	cast to a pool item used for storing an object in a quick pool, or cast
*	to a list item used for storing an object in a quick list.  This removes
*	the need to embed a map item, a list item, and a pool item in objects
*	that need to be stored in a quick list, a quick pool, and a quick map.
*
* SEE ALSO
*	Quick Map, cl_qmap_insert, cl_qmap_key, cl_pool_item_t, cl_list_item_t
*********/

/****s* Component Library: Quick Map/cl_map_obj_t
* NAME
*	cl_map_obj_t
*
* DESCRIPTION
*	The cl_map_obj_t structure is used to store objects in maps.
*
*	The cl_map_obj_t structure should be treated as opaque and should
*	be manipulated only through the provided functions.
*
* SYNOPSIS
*/
typedef struct _cl_map_obj {
	cl_map_item_t item;
	const void *p_object;
} cl_map_obj_t;
/*
* FIELDS
*	item
*		Map item used by internally by the map to store an object.
*
*	p_object
*		User defined context. Users should not access this field directly.
*		Use cl_qmap_set_obj and cl_qmap_obj to set and retrieve the value
*		of this field.
*
* NOTES
*	None of the fields of this structure should be manipulated by users, as
*	they are crititcal to the proper operation of the map in which they
*	are stored.
*
*	Use cl_qmap_set_obj and cl_qmap_obj to set and retrieve the object
*	stored in a map item, respectively.
*
* SEE ALSO
*	Quick Map, cl_qmap_set_obj, cl_qmap_obj, cl_map_item_t
*********/

/****s* Component Library: Quick Map/cl_qmap_t
* NAME
*	cl_qmap_t
*
* DESCRIPTION
*	Quick map structure.
*
*	The cl_qmap_t structure should be treated as opaque and should
*	be manipulated only through the provided functions.
*
* SYNOPSIS
*/
typedef struct _cl_qmap {
	cl_map_item_t root;
	cl_map_item_t nil;
	size_t count;
} cl_qmap_t;
/*
* PARAMETERS
*	root
*		Map item that serves as root of the map.  The root is set up to
*		always have itself as parent.  The left pointer is set to point
*		to the item at the root.
*
*	nil
*		Map item that serves as terminator for all leaves, as well as
*		providing the list item used as quick list for storing map items
*		in a list for faster traversal.
*
*	state
*		State of the map, used to verify that operations are permitted.
*
*	count
*		Number of items in the map.
*
* SEE ALSO
*	Quick Map
*********/

/****d* Component Library: Quick Map/cl_pfn_qmap_apply_t
* NAME
*	cl_pfn_qmap_apply_t
*
* DESCRIPTION
*	The cl_pfn_qmap_apply_t function type defines the prototype for
*	functions used to iterate items in a quick map.
*
* SYNOPSIS
*/
typedef void
 (*cl_pfn_qmap_apply_t) (cl_map_item_t * const p_map_item, void *context);
/*
* PARAMETERS
*	p_map_item
*		[in] Pointer to a cl_map_item_t structure.
*
*	context
*		[in] Value passed to the callback function.
*
* RETURN VALUE
*	This function does not return a value.
*
* NOTES
*	This function type is provided as function prototype reference for the
*	function provided by users as a parameter to the cl_qmap_apply_func
*	function.
*
* SEE ALSO
*	Quick Map, cl_qmap_apply_func
*********/

/****f* Component Library: Quick Map/cl_qmap_count
* NAME
*	cl_qmap_count
*
* DESCRIPTION
*	The cl_qmap_count function returns the number of items stored
*	in a quick map.
*
* SYNOPSIS
*/
static inline uint32_t cl_qmap_count(const cl_qmap_t * const p_map)
{
	assert(p_map);
	return ((uint32_t) p_map->count);
}

/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure whose item count to return.
*
* RETURN VALUE
*	Returns the number of items stored in the map.
*
* SEE ALSO
*	Quick Map, cl_is_qmap_empty
*********/

/****f* Component Library: Quick Map/cl_is_qmap_empty
* NAME
*	cl_is_qmap_empty
*
* DESCRIPTION
*	The cl_is_qmap_empty function returns whether a quick map is empty.
*
* SYNOPSIS
*/
static inline bool cl_is_qmap_empty(const cl_qmap_t * const p_map)
{
	assert(p_map);

	return (p_map->count == 0);
}

/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure to test for emptiness.
*
* RETURN VALUES
*	TRUE if the quick map is empty.
*
*	FALSE otherwise.
*
* SEE ALSO
*	Quick Map, cl_qmap_count, cl_qmap_remove_all
*********/

/****f* Component Library: Quick Map/cl_qmap_set_obj
* NAME
*	cl_qmap_set_obj
*
* DESCRIPTION
*	The cl_qmap_set_obj function sets the object stored in a map object.
*
* SYNOPSIS
*/
static inline void
cl_qmap_set_obj(cl_map_obj_t * const p_map_obj,
		const void *const p_object)
{
	assert(p_map_obj);
	p_map_obj->p_object = p_object;
}

/*
* PARAMETERS
*	p_map_obj
*		[in] Pointer to a map object stucture whose object pointer
*		is to be set.
*
*	p_object
*		[in] User defined context.
*
* RETURN VALUE
*	This function does not return a value.
*
* SEE ALSO
*	Quick Map, cl_qmap_obj
*********/

/****f* Component Library: Quick Map/cl_qmap_obj
* NAME
*	cl_qmap_obj
*
* DESCRIPTION
*	The cl_qmap_obj function returns the object stored in a map object.
*
* SYNOPSIS
*/
static inline void *cl_qmap_obj(const cl_map_obj_t * const p_map_obj)
{
	assert(p_map_obj);
	return ((void *)p_map_obj->p_object);
}

/*
* PARAMETERS
*	p_map_obj
*		[in] Pointer to a map object stucture whose object pointer to return.
*
* RETURN VALUE
*	Returns the value of the object pointer stored in the map object.
*
* SEE ALSO
*	Quick Map, cl_qmap_set_obj
*********/

/****f* Component Library: Quick Map/cl_qmap_key
* NAME
*	cl_qmap_key
*
* DESCRIPTION
*	The cl_qmap_key function retrieves the key value of a map item.
*
* SYNOPSIS
*/
static inline uint64_t cl_qmap_key(const cl_map_item_t * const p_item)
{
	assert(p_item);
	return (p_item->key);
}

/*
* PARAMETERS
*	p_item
*		[in] Pointer to a map item whose key value to return.
*
* RETURN VALUE
*	Returns the 64-bit key value for the specified map item.
*
* NOTES
*	The key value is set in a call to cl_qmap_insert.
*
* SEE ALSO
*	Quick Map, cl_qmap_insert
*********/

/****f* Component Library: Quick Map/cl_qmap_init
* NAME
*	cl_qmap_init
*
* DESCRIPTION
*	The cl_qmap_init function initialized a quick map for use.
*
* SYNOPSIS
*/
void cl_qmap_init(cl_qmap_t * const p_map);
/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure to initialize.
*
* RETURN VALUES
*	This function does not return a value.
*
* NOTES
*	Allows calling quick map manipulation functions.
*
* SEE ALSO
*	Quick Map, cl_qmap_insert, cl_qmap_remove
*********/

/****f* Component Library: Quick Map/cl_qmap_end
* NAME
*	cl_qmap_end
*
* DESCRIPTION
*	The cl_qmap_end function returns the end of a quick map.
*
* SYNOPSIS
*/
static inline const cl_map_item_t *cl_qmap_end(const cl_qmap_t * const p_map)
{
	assert(p_map);
	/* Nil is the end of the map. */
	return (&p_map->nil);
}

/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure whose end to return.
*
* RETURN VALUE
*	Pointer to the end of the map.
*
* NOTES
*	cl_qmap_end is useful for determining the validity of map items returned
*	by cl_qmap_head, cl_qmap_tail, cl_qmap_next, or cl_qmap_prev.  If the
*	map item pointer returned by any of these functions compares to the end,
*	the end of the map was encoutered.
*	When using cl_qmap_head or cl_qmap_tail, this condition indicates that
*	the map is empty.
*
* SEE ALSO
*	Quick Map, cl_qmap_head, cl_qmap_tail, cl_qmap_next, cl_qmap_prev
*********/

/****f* Component Library: Quick Map/cl_qmap_head
* NAME
*	cl_qmap_head
*
* DESCRIPTION
*	The cl_qmap_head function returns the map item with the lowest key
*	value stored in a quick map.
*
* SYNOPSIS
*/
static inline cl_map_item_t *cl_qmap_head(const cl_qmap_t * const p_map)
{
	assert(p_map);
	return ((cl_map_item_t *) p_map->nil.pool_item.list_item.p_next);
}

/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure whose item with the lowest
*		key is returned.
*
* RETURN VALUES
*	Pointer to the map item with the lowest key in the quick map.
*
*	Pointer to the map end if the quick map was empty.
*
* NOTES
*	cl_qmap_head does not remove the item from the map.
*
* SEE ALSO
*	Quick Map, cl_qmap_tail, cl_qmap_next, cl_qmap_prev, cl_qmap_end,
*	cl_qmap_item_t
*********/

/****f* Component Library: Quick Map/cl_qmap_tail
* NAME
*	cl_qmap_tail
*
* DESCRIPTION
*	The cl_qmap_tail function returns the map item with the highest key
*	value stored in a quick map.
*
* SYNOPSIS
*/
static inline cl_map_item_t *cl_qmap_tail(const cl_qmap_t * const p_map)
{
	assert(p_map);
	return ((cl_map_item_t *) p_map->nil.pool_item.list_item.p_prev);
}

/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure whose item with the
*		highest key is returned.
*
* RETURN VALUES
*	Pointer to the map item with the highest key in the quick map.
*
*	Pointer to the map end if the quick map was empty.
*
* NOTES
*	cl_qmap_end does not remove the item from the map.
*
* SEE ALSO
*	Quick Map, cl_qmap_head, cl_qmap_next, cl_qmap_prev, cl_qmap_end,
*	cl_qmap_item_t
*********/

/****f* Component Library: Quick Map/cl_qmap_next
* NAME
*	cl_qmap_next
*
* DESCRIPTION
*	The cl_qmap_next function returns the map item with the next higher
*	key value than a specified map item.
*
* SYNOPSIS
*/
static inline cl_map_item_t *cl_qmap_next(const cl_map_item_t * const p_item)
{
	assert(p_item);
	return ((cl_map_item_t *) p_item->pool_item.list_item.p_next);
}

/*
* PARAMETERS
*	p_item
*		[in] Pointer to a map item whose successor to return.
*
* RETURN VALUES
*	Pointer to the map item with the next higher key value in a quick map.
*
*	Pointer to the map end if the specified item was the last item in
*	the quick map.
*
* SEE ALSO
*	Quick Map, cl_qmap_head, cl_qmap_tail, cl_qmap_prev, cl_qmap_end,
*	cl_map_item_t
*********/

/****f* Component Library: Quick Map/cl_qmap_prev
* NAME
*	cl_qmap_prev
*
* DESCRIPTION
*	The cl_qmap_prev function returns the map item with the next lower
*	key value than a precified map item.
*
* SYNOPSIS
*/
static inline cl_map_item_t *cl_qmap_prev(const cl_map_item_t * const p_item)
{
	assert(p_item);
	return ((cl_map_item_t *) p_item->pool_item.list_item.p_prev);
}

/*
* PARAMETERS
*	p_item
*		[in] Pointer to a map item whose predecessor to return.
*
* RETURN VALUES
*	Pointer to the map item with the next lower key value in a quick map.
*
*	Pointer to the map end if the specifid item was the first item in
*	the quick map.
*
* SEE ALSO
*	Quick Map, cl_qmap_head, cl_qmap_tail, cl_qmap_next, cl_qmap_end,
*	cl_map_item_t
*********/

/****f* Component Library: Quick Map/cl_qmap_insert
* NAME
*	cl_qmap_insert
*
* DESCRIPTION
*	The cl_qmap_insert function inserts a map item into a quick map.
*  NOTE: Only if such a key does not alerady exist in the map !!!!
*
* SYNOPSIS
*/
cl_map_item_t *cl_qmap_insert(cl_qmap_t * const p_map,
			      const uint64_t key,
			      cl_map_item_t * const p_item);
/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure into which to add the item.
*
*	key
*		[in] Value to assign to the item.
*
*	p_item
*		[in] Pointer to a cl_map_item_t stucture to insert into the quick map.
*
* RETURN VALUE
*	Pointer to the item in the map with the specified key.  If insertion
*	was successful, this is the pointer to the item.  If an item with the
*	specified key already exists in the map, the pointer to that item is
*	returned - but the new key is NOT inserted...
*
* NOTES
*	Insertion operations may cause the quick map to rebalance.
*
* SEE ALSO
*	Quick Map, cl_qmap_remove, cl_map_item_t
*********/

/****f* Component Library: Quick Map/cl_qmap_get
* NAME
*	cl_qmap_get
*
* DESCRIPTION
*	The cl_qmap_get function returns the map item associated with a key.
*
* SYNOPSIS
*/
cl_map_item_t *cl_qmap_get(const cl_qmap_t * const p_map,
			   const uint64_t key);
/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure from which to retrieve the
*		item with the specified key.
*
*	key
*		[in] Key value used to search for the desired map item.
*
* RETURN VALUES
*	Pointer to the map item with the desired key value.
*
*	Pointer to the map end if there was no item with the desired key value
*	stored in the quick map.
*
* NOTES
*	cl_qmap_get does not remove the item from the quick map.
*
* SEE ALSO
*	Quick Map, cl_qmap_get_next, cl_qmap_remove
*********/

/****f* Component Library: Quick Map/cl_qmap_get_next
* NAME
*	cl_qmap_get_next
*
* DESCRIPTION
*	The cl_qmap_get_next function returns the first map item associated with a
*	key > the key specified.
*
* SYNOPSIS
*/
cl_map_item_t *cl_qmap_get_next(const cl_qmap_t * const p_map,
				const uint64_t key);
/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure from which to retrieve the
*		first item with a key > the specified key.
*
*	key
*		[in] Key value used to search for the desired map item.
*
* RETURN VALUES
*	Pointer to the first map item with a key > the desired key value.
*
*	Pointer to the map end if there was no item with a key > the desired key
*	value stored in the quick map.
*
* NOTES
*	cl_qmap_get_next does not remove the item from the quick map.
*
* SEE ALSO
*	Quick Map, cl_qmap_get, cl_qmap_remove
*********/

/****f* Component Library: Quick Map/cl_qmap_remove_item
* NAME
*	cl_qmap_remove_item
*
* DESCRIPTION
*	The cl_qmap_remove_item function removes the specified map item
*	from a quick map.
*
* SYNOPSIS
*/
void
cl_qmap_remove_item(cl_qmap_t * const p_map,
		    cl_map_item_t * const p_item);
/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure from which to
*		remove item.
*
*	p_item
*		[in] Pointer to a map item to remove from its quick map.
*
* RETURN VALUES
*	This function does not return a value.
*
*	In a debug build, cl_qmap_remove_item asserts that the item being removed
*	is in the specified map.
*
* NOTES
*	Removes the map item pointed to by p_item from its quick map.
*
* SEE ALSO
*	Quick Map, cl_qmap_remove, cl_qmap_remove_all, cl_qmap_insert
*********/

/****f* Component Library: Quick Map/cl_qmap_remove
* NAME
*	cl_qmap_remove
*
* DESCRIPTION
*	The cl_qmap_remove function removes the map item with the specified key
*	from a quick map.
*
* SYNOPSIS
*/
cl_map_item_t *cl_qmap_remove(cl_qmap_t * const p_map,
			      const uint64_t key);
/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure from which to remove the item
*		with the specified key.
*
*	key
*		[in] Key value used to search for the map item to remove.
*
* RETURN VALUES
*	Pointer to the removed map item if it was found.
*
*	Pointer to the map end if no item with the specified key exists in the
*	quick map.
*
* SEE ALSO
*	Quick Map, cl_qmap_remove_item, cl_qmap_remove_all, cl_qmap_insert
*********/

/****f* Component Library: Quick Map/cl_qmap_remove_all
* NAME
*	cl_qmap_remove_all
*
* DESCRIPTION
*	The cl_qmap_remove_all function removes all items in a quick map,
*	leaving it empty.
*
* SYNOPSIS
*/
static inline void cl_qmap_remove_all(cl_qmap_t * const p_map)
{
	assert(p_map);

	p_map->root.p_left = &p_map->nil;
	p_map->nil.pool_item.list_item.p_next = &p_map->nil.pool_item.list_item;
	p_map->nil.pool_item.list_item.p_prev = &p_map->nil.pool_item.list_item;
	p_map->count = 0;
}

/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure to empty.
*
* RETURN VALUES
*	This function does not return a value.
*
* SEE ALSO
*	Quick Map, cl_qmap_remove, cl_qmap_remove_item
*********/

/****f* Component Library: Quick Map/cl_qmap_merge
* NAME
*	cl_qmap_merge
*
* DESCRIPTION
*	The cl_qmap_merge function moves all items from one map to another,
*	excluding duplicates.
*
* SYNOPSIS
*/
void
cl_qmap_merge(cl_qmap_t * const p_dest_map,
	      cl_qmap_t * const p_src_map);
/*
* PARAMETERS
*	p_dest_map
*		[out] Pointer to a cl_qmap_t structure to which items should be added.
*
*	p_src_map
*		[in/out] Pointer to a cl_qmap_t structure whose items to add
*		to p_dest_map.
*
* RETURN VALUES
*	This function does not return a value.
*
* NOTES
*	Items are evaluated based on their keys only.
*
*	Upon return from cl_qmap_merge, the quick map referenced by p_src_map
*	contains all duplicate items.
*
* SEE ALSO
*	Quick Map, cl_qmap_delta
*********/

/****f* Component Library: Quick Map/cl_qmap_delta
* NAME
*	cl_qmap_delta
*
* DESCRIPTION
*	The cl_qmap_delta function computes the differences between two maps.
*
* SYNOPSIS
*/
void
cl_qmap_delta(cl_qmap_t * const p_map1,
	      cl_qmap_t * const p_map2,
	      cl_qmap_t * const p_new, cl_qmap_t * const p_old);
/*
* PARAMETERS
*	p_map1
*		[in/out] Pointer to the first of two cl_qmap_t structures whose
*		differences to compute.
*
*	p_map2
*		[in/out] Pointer to the second of two cl_qmap_t structures whose
*		differences to compute.
*
*	p_new
*		[out] Pointer to an empty cl_qmap_t structure that contains the
*		items unique to p_map2 upon return from the function.
*
*	p_old
*		[out] Pointer to an empty cl_qmap_t structure that contains the
*		items unique to p_map1 upon return from the function.
*
* RETURN VALUES
*	This function does not return a value.
*
* NOTES
*	Items are evaluated based on their keys.  Items that exist in both
*	p_map1 and p_map2 remain in their respective maps.  Items that
*	exist only p_map1 are moved to p_old.  Likewise, items that exist only
*	in p_map2 are moved to p_new.  This function can be useful in evaluating
*	changes between two maps.
*
*	Both maps pointed to by p_new and p_old must be empty on input.  This
*	requirement removes the possibility of failures.
*
* SEE ALSO
*	Quick Map, cl_qmap_merge
*********/

/****f* Component Library: Quick Map/cl_qmap_apply_func
* NAME
*	cl_qmap_apply_func
*
* DESCRIPTION
*	The cl_qmap_apply_func function executes a specified function
*	for every item stored in a quick map.
*
* SYNOPSIS
*/
void
cl_qmap_apply_func(const cl_qmap_t * const p_map,
		   cl_pfn_qmap_apply_t pfn_func,
		   const void *const context);
/*
* PARAMETERS
*	p_map
*		[in] Pointer to a cl_qmap_t structure.
*
*	pfn_func
*		[in] Function invoked for every item in the quick map.
*		See the cl_pfn_qmap_apply_t function type declaration for
*		details about the callback function.
*
*	context
*		[in] Value to pass to the callback functions to provide context.
*
* RETURN VALUE
*	This function does not return a value.
*
* NOTES
*	The function provided must not perform any map operations, as these
*	would corrupt the quick map.
*
* SEE ALSO
*	Quick Map, cl_pfn_qmap_apply_t
*********/

#endif				/* _CL_QMAP_H_ */
