|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This file is provided under a dual BSD/GPLv2 license. When using or
|
|
Packit |
961e70 |
redistributing this file, you may do so under either license.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
GPL LICENSE SUMMARY
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Copyright(c) 2015 Intel Corporation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This program is free software; you can redistribute it and/or modify
|
|
Packit |
961e70 |
it under the terms of version 2 of the GNU General Public License as
|
|
Packit |
961e70 |
published by the Free Software Foundation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This program is distributed in the hope that it will be useful, but
|
|
Packit |
961e70 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
961e70 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
961e70 |
General Public License for more details.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Contact Information:
|
|
Packit |
961e70 |
Intel Corporation, www.intel.com
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
BSD LICENSE
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Copyright(c) 2015 Intel Corporation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
961e70 |
modification, are permitted provided that the following conditions
|
|
Packit |
961e70 |
are met:
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
* Redistributions of source code must retain the above copyright
|
|
Packit |
961e70 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
961e70 |
* Redistributions in binary form must reproduce the above copyright
|
|
Packit |
961e70 |
notice, this list of conditions and the following disclaimer in
|
|
Packit |
961e70 |
the documentation and/or other materials provided with the
|
|
Packit |
961e70 |
distribution.
|
|
Packit |
961e70 |
* Neither the name of Intel Corporation nor the names of its
|
|
Packit |
961e70 |
contributors may be used to endorse or promote products derived
|
|
Packit |
961e70 |
from this software without specific prior written permission.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
961e70 |
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
961e70 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
961e70 |
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
961e70 |
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
961e70 |
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
961e70 |
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
961e70 |
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
961e70 |
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
961e70 |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
961e70 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Copyright (c) 2003-2015 Intel Corporation. All rights reserved. */
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Abstract:
|
|
Packit |
961e70 |
* Implementation of quick map, a binary tree where the caller always provides
|
|
Packit |
961e70 |
* all necessary storage.
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* Environment:
|
|
Packit |
961e70 |
* All
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* $Revision$
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*****************************************************************************
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* Map
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* Map is an associative array. By providing a key, the caller can retrieve
|
|
Packit |
961e70 |
* an object from the map. All objects in the map have an associated key,
|
|
Packit |
961e70 |
* as specified by the caller when the object was inserted into the map.
|
|
Packit |
961e70 |
* In addition to random access, the caller can traverse the map much like
|
|
Packit |
961e70 |
* a linked list, either forwards from the first object or backwards from
|
|
Packit |
961e70 |
* the last object. The objects in the map are always traversed in
|
|
Packit |
961e70 |
* order since the nodes are stored sorted.
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* This implementation of Map uses a red black tree verified against
|
|
Packit |
961e70 |
* Cormen-Leiserson-Rivest text, McGraw-Hill Edition, fourteenth
|
|
Packit |
961e70 |
* printing, 1994.
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
*****************************************************************************/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#include <string.h> /* for memset declaration */
|
|
Packit |
961e70 |
|
|
Packit Service |
7ed5cc |
// RBTREE_CMP should be a comparator, i.e. RBTREE_CMP(a, b) should evaluate to
|
|
Packit Service |
7ed5cc |
// -1, 0, or 1 depending on if a < b, a == b, or a > b, respectively.
|
|
Packit Service |
7ed5cc |
#ifdef RBTREE_CMP
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
#if defined(RBTREE_GET_LEFTMOST) || defined(RBTREE_GET_RIGHTMOST)
|
|
Packit Service |
7ed5cc |
#error Cannot define both RBTREE_CMP and RBTREE_GET_(LEFT|RIGHT)MOST
|
|
Packit Service |
7ed5cc |
#endif
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
#elif !defined ( RBTREE_GET_LEFTMOST ) || \
|
|
Packit |
961e70 |
! defined ( RBTREE_GET_RIGHTMOST ) || \
|
|
Packit |
961e70 |
! defined ( RBTREE_MAP_COUNT ) || \
|
|
Packit |
961e70 |
! defined ( RBTREE_ASSERT )
|
|
Packit |
961e70 |
#error "You must define RBTREE_GET_LEFTMOST and RBTREE_GET_RIGHTMOST and \
|
|
Packit |
961e70 |
RBTREE_MAP_COUNT and RBTREE_ASSERT before including rbtree.c"
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
#endif /* RBTREE_CMP */
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#define IN /* nothing */
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/******************************************************************************
|
|
Packit |
961e70 |
*******************************************************************************
|
|
Packit |
961e70 |
************** ************
|
|
Packit |
961e70 |
************** IMPLEMENTATION OF QUICK MAP ************
|
|
Packit |
961e70 |
************** ************
|
|
Packit |
961e70 |
*******************************************************************************
|
|
Packit |
961e70 |
******************************************************************************/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Forward declarations: */
|
|
Packit |
961e70 |
static void ips_cl_qmap_init(
|
|
Packit |
961e70 |
IN cl_qmap_t *p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* const root,
|
|
Packit |
961e70 |
IN cl_map_item_t* const nil);
|
|
Packit |
961e70 |
static void ips_cl_qmap_insert_item(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* const p_item);
|
|
Packit |
961e70 |
static void ips_cl_qmap_remove_item(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* const p_item);
|
|
Packit |
961e70 |
static cl_map_item_t* ips_cl_qmap_successor(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN const cl_map_item_t* p_item);
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
#ifndef RBTREE_NO_EMIT_IPS_CL_QMAP_PREDECESSOR
|
|
Packit |
961e70 |
static cl_map_item_t* ips_cl_qmap_predecessor(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN const cl_map_item_t* p_item);
|
|
Packit Service |
7ed5cc |
#endif
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
#if defined(RBTREE_GET_LEFTMOST)
|
|
Packit |
961e70 |
static cl_map_item_t* ips_cl_qmap_search(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN unsigned long start,
|
|
Packit |
961e70 |
IN unsigned long end);
|
|
Packit Service |
7ed5cc |
#else
|
|
Packit Service |
7ed5cc |
static cl_map_item_t* ips_cl_qmap_searchv(
|
|
Packit Service |
7ed5cc |
cl_qmap_t* const p_map,
|
|
Packit Service |
7ed5cc |
const RBTREE_MI_PL *key);
|
|
Packit Service |
7ed5cc |
#endif
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Get the root.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static inline cl_map_item_t*
|
|
Packit |
961e70 |
__cl_map_root(
|
|
Packit |
961e70 |
IN const cl_qmap_t* const p_map )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map );
|
|
Packit |
961e70 |
return( p_map->root->p_left );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Returns whether a given item is on the left of its parent.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static int
|
|
Packit |
961e70 |
__cl_map_is_left_child(
|
|
Packit |
961e70 |
IN const cl_map_item_t* const p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item->p_up );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item->p_up != p_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
return( p_item->p_up->p_left == p_item );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Retrieve the pointer to the parent's pointer to an item.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static cl_map_item_t**
|
|
Packit |
961e70 |
__cl_map_get_parent_ptr_to_item(
|
|
Packit |
961e70 |
IN cl_map_item_t* const p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item->p_up );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item->p_up != p_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( __cl_map_is_left_child( p_item ) )
|
|
Packit |
961e70 |
return( &p_item->p_up->p_left );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item->p_up->p_right == p_item );
|
|
Packit |
961e70 |
return( &p_item->p_up->p_right );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Rotate a node to the left. This rotation affects the least number of links
|
|
Packit |
961e70 |
* between nodes and brings the level of C up by one while increasing the depth
|
|
Packit |
961e70 |
* of A one. Note that the links to/from W, X, Y, and Z are not affected.
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* R R
|
|
Packit |
961e70 |
* | |
|
|
Packit |
961e70 |
* A C
|
|
Packit |
961e70 |
* / \ / \
|
|
Packit |
961e70 |
* W C A Z
|
|
Packit |
961e70 |
* / \ / \
|
|
Packit |
961e70 |
* B Z W B
|
|
Packit |
961e70 |
* / \ / \
|
|
Packit |
961e70 |
* X Y X Y
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static void
|
|
Packit |
961e70 |
__cl_map_rot_left(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* const p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t **pp_root;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item->p_right != p_map->nil_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
pp_root = __cl_map_get_parent_ptr_to_item( p_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Point R to C instead of A. */
|
|
Packit |
961e70 |
*pp_root = p_item->p_right;
|
|
Packit |
961e70 |
/* Set C's parent to R. */
|
|
Packit |
961e70 |
(*pp_root)->p_up = p_item->p_up;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Set A's right to B */
|
|
Packit |
961e70 |
p_item->p_right = (*pp_root)->p_left;
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Set B's parent to A. We trap for B being NIL since the
|
|
Packit |
961e70 |
* caller may depend on NIL not changing.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
if( (*pp_root)->p_left != p_map->nil_item )
|
|
Packit |
961e70 |
(*pp_root)->p_left->p_up = p_item;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Set C's left to A. */
|
|
Packit |
961e70 |
(*pp_root)->p_left = p_item;
|
|
Packit |
961e70 |
/* Set A's parent to C. */
|
|
Packit |
961e70 |
p_item->p_up = *pp_root;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Rotate a node to the right. This rotation affects the least number of links
|
|
Packit |
961e70 |
* between nodes and brings the level of A up by one while increasing the depth
|
|
Packit |
961e70 |
* of C one. Note that the links to/from W, X, Y, and Z are not affected.
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* R R
|
|
Packit |
961e70 |
* | |
|
|
Packit |
961e70 |
* C A
|
|
Packit |
961e70 |
* / \ / \
|
|
Packit |
961e70 |
* A Z W C
|
|
Packit |
961e70 |
* / \ / \
|
|
Packit |
961e70 |
* W B B Z
|
|
Packit |
961e70 |
* / \ / \
|
|
Packit |
961e70 |
* X Y X Y
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static void
|
|
Packit |
961e70 |
__cl_map_rot_right(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* const p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t **pp_root;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item->p_left != p_map->nil_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Point R to A instead of C. */
|
|
Packit |
961e70 |
pp_root = __cl_map_get_parent_ptr_to_item( p_item );
|
|
Packit |
961e70 |
(*pp_root) = p_item->p_left;
|
|
Packit |
961e70 |
/* Set A's parent to R. */
|
|
Packit |
961e70 |
(*pp_root)->p_up = p_item->p_up;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Set C's left to B */
|
|
Packit |
961e70 |
p_item->p_left = (*pp_root)->p_right;
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Set B's parent to C. We trap for B being NIL since the
|
|
Packit |
961e70 |
* caller may depend on NIL not changing.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
if( (*pp_root)->p_right != p_map->nil_item )
|
|
Packit |
961e70 |
(*pp_root)->p_right->p_up = p_item;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Set A's right to C. */
|
|
Packit |
961e70 |
(*pp_root)->p_right = p_item;
|
|
Packit |
961e70 |
/* Set C's parent to A. */
|
|
Packit |
961e70 |
p_item->p_up = *pp_root;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Balance a tree starting at a given item back to the root.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static void
|
|
Packit |
961e70 |
__cl_map_ins_bal(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t* p_grand_uncle;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item != p_map->root );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
while( p_item->p_up->color == CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
if( __cl_map_is_left_child( p_item->p_up ) )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_grand_uncle = p_item->p_up->p_up->p_right;
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_grand_uncle );
|
|
Packit |
961e70 |
if( p_grand_uncle->color == CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_grand_uncle->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_item->p_up->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_item->p_up->p_up->color = CL_MAP_RED;
|
|
Packit |
961e70 |
p_item = p_item->p_up->p_up;
|
|
Packit |
961e70 |
continue;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( !__cl_map_is_left_child( p_item ) )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_item = p_item->p_up;
|
|
Packit |
961e70 |
__cl_map_rot_left( p_map, p_item );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
p_item->p_up->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_item->p_up->p_up->color = CL_MAP_RED;
|
|
Packit |
961e70 |
__cl_map_rot_right( p_map, p_item->p_up->p_up );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
else
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_grand_uncle = p_item->p_up->p_up->p_left;
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_grand_uncle );
|
|
Packit |
961e70 |
if( p_grand_uncle->color == CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_grand_uncle->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_item->p_up->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_item->p_up->p_up->color = CL_MAP_RED;
|
|
Packit |
961e70 |
p_item = p_item->p_up->p_up;
|
|
Packit |
961e70 |
continue;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( __cl_map_is_left_child( p_item ) )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_item = p_item->p_up;
|
|
Packit |
961e70 |
__cl_map_rot_right( p_map, p_item );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
p_item->p_up->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_item->p_up->p_up->color = CL_MAP_RED;
|
|
Packit |
961e70 |
__cl_map_rot_left( p_map, p_item->p_up->p_up );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static void ips_cl_qmap_init(
|
|
Packit |
961e70 |
IN cl_qmap_t *p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* const root,
|
|
Packit |
961e70 |
IN cl_map_item_t* const nil_item)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map );
|
|
Packit |
961e70 |
RBTREE_ASSERT( root );
|
|
Packit |
961e70 |
RBTREE_ASSERT( nil_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
memset(p_map,0,sizeof(cl_qmap_t));
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
p_map->root = root;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* setup the RB tree map */
|
|
Packit |
961e70 |
p_map->nil_item = nil_item;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
p_map->root->p_up = p_map->root;
|
|
Packit |
961e70 |
p_map->root->p_left = p_map->nil_item;
|
|
Packit |
961e70 |
p_map->root->p_right = p_map->nil_item;
|
|
Packit |
961e70 |
p_map->root->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
p_map->nil_item->p_up = p_map->nil_item;
|
|
Packit |
961e70 |
p_map->nil_item->p_left = p_map->nil_item;
|
|
Packit |
961e70 |
p_map->nil_item->p_right = p_map->nil_item;
|
|
Packit |
961e70 |
p_map->nil_item->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static void
|
|
Packit |
961e70 |
ips_cl_qmap_insert_item(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* const p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t *p_insert_at, *p_comp_item;
|
|
Packit |
961e70 |
int compare_res = 0;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map->root->p_up == p_map->root );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map->root->color != CL_MAP_RED );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map->nil_item->color != CL_MAP_RED );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Find the insertion location. */
|
|
Packit |
961e70 |
p_insert_at = p_map->root;
|
|
Packit |
961e70 |
p_comp_item = __cl_map_root( p_map );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
while( p_comp_item != p_map->nil_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_insert_at = p_comp_item;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Traverse the tree until the correct insertion point is found. */
|
|
Packit Service |
7ed5cc |
#ifdef RBTREE_GET_LEFTMOST
|
|
Packit |
961e70 |
if( RBTREE_GET_LEFTMOST(&p_item->payload) < RBTREE_GET_LEFTMOST(&p_insert_at->payload) )
|
|
Packit Service |
7ed5cc |
#else
|
|
Packit Service |
7ed5cc |
if(RBTREE_CMP(&p_item->payload, &p_insert_at->payload) < 0)
|
|
Packit Service |
7ed5cc |
#endif
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_comp_item = p_insert_at->p_left;
|
|
Packit |
961e70 |
compare_res = 1;
|
|
Packit |
961e70 |
} else {
|
|
Packit |
961e70 |
p_comp_item = p_insert_at->p_right;
|
|
Packit |
961e70 |
compare_res = -1;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_insert_at != p_map->nil_item );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_comp_item == p_map->nil_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Insert the item. */
|
|
Packit |
961e70 |
p_item->p_left = p_map->nil_item;
|
|
Packit |
961e70 |
p_item->p_right = p_map->nil_item;
|
|
Packit |
961e70 |
p_item->color = CL_MAP_RED;
|
|
Packit |
961e70 |
if( p_insert_at == p_map->root )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_insert_at->p_left = p_item;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
else if( compare_res > 0 ) /* key < p_insert_at->key */
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_insert_at->p_left = p_item;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
else
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_insert_at->p_right = p_item;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
/* Increase the count. */
|
|
Packit |
961e70 |
RBTREE_MAP_COUNT(&p_map->payload)++;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
p_item->p_up = p_insert_at;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* We have added depth to this section of the tree.
|
|
Packit |
961e70 |
* Rebalance as necessary as we retrace our path through the tree
|
|
Packit |
961e70 |
* and update colors.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
__cl_map_ins_bal( p_map, p_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
__cl_map_root( p_map )->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Note that it is not necessary to re-color the nil node black because all
|
|
Packit |
961e70 |
* red color assignments are made via the p_up pointer, and nil is never
|
|
Packit |
961e70 |
* set as the value of a p_up pointer.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static void
|
|
Packit |
961e70 |
__cl_map_del_bal(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t *p_uncle;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
while( (p_item->color != CL_MAP_RED) && (p_item->p_up != p_map->root) )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
if( __cl_map_is_left_child( p_item ) )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_uncle = p_item->p_up->p_right;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( p_uncle->color == CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_uncle->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_item->p_up->color = CL_MAP_RED;
|
|
Packit |
961e70 |
__cl_map_rot_left( p_map, p_item->p_up );
|
|
Packit |
961e70 |
p_uncle = p_item->p_up->p_right;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( p_uncle->p_right->color != CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
if( p_uncle->p_left->color != CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_uncle->color = CL_MAP_RED;
|
|
Packit |
961e70 |
p_item = p_item->p_up;
|
|
Packit |
961e70 |
continue;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
p_uncle->p_left->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_uncle->color = CL_MAP_RED;
|
|
Packit |
961e70 |
__cl_map_rot_right( p_map, p_uncle );
|
|
Packit |
961e70 |
p_uncle = p_item->p_up->p_right;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
p_uncle->color = p_item->p_up->color;
|
|
Packit |
961e70 |
p_item->p_up->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_uncle->p_right->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
__cl_map_rot_left( p_map, p_item->p_up );
|
|
Packit |
961e70 |
break;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
else
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_uncle = p_item->p_up->p_left;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( p_uncle->color == CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_uncle->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_item->p_up->color = CL_MAP_RED;
|
|
Packit |
961e70 |
__cl_map_rot_right( p_map, p_item->p_up );
|
|
Packit |
961e70 |
p_uncle = p_item->p_up->p_left;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( p_uncle->p_left->color != CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
if( p_uncle->p_right->color != CL_MAP_RED )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
p_uncle->color = CL_MAP_RED;
|
|
Packit |
961e70 |
p_item = p_item->p_up;
|
|
Packit |
961e70 |
continue;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
p_uncle->p_right->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_uncle->color = CL_MAP_RED;
|
|
Packit |
961e70 |
__cl_map_rot_left( p_map, p_uncle );
|
|
Packit |
961e70 |
p_uncle = p_item->p_up->p_left;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
p_uncle->color = p_item->p_up->color;
|
|
Packit |
961e70 |
p_item->p_up->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
p_uncle->p_left->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
__cl_map_rot_right( p_map, p_item->p_up );
|
|
Packit |
961e70 |
break;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
p_item->color = CL_MAP_BLACK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static void
|
|
Packit |
961e70 |
ips_cl_qmap_remove_item(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN cl_map_item_t* const p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t *p_child, *p_del_item;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map );
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_item );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( p_item == p_map->nil_item )
|
|
Packit |
961e70 |
return;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( (p_item->p_right == p_map->nil_item) || (p_item->p_left == p_map->nil_item ) )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
/* The item being removed has children on at most on side. */
|
|
Packit |
961e70 |
p_del_item = p_item;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
else
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* The item being removed has children on both side.
|
|
Packit |
961e70 |
* We select the item that will replace it. After removing
|
|
Packit |
961e70 |
* the substitute item and rebalancing, the tree will have the
|
|
Packit |
961e70 |
* correct topology. Exchanging the substitute for the item
|
|
Packit |
961e70 |
* will finalize the removal.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
p_del_item = ips_cl_qmap_successor(p_map, p_item);
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_del_item != p_map->nil_item );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_MAP_COUNT(&p_map->payload)--;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Get the pointer to the new root's child, if any. */
|
|
Packit |
961e70 |
if( p_del_item->p_left != p_map->nil_item )
|
|
Packit |
961e70 |
p_child = p_del_item->p_left;
|
|
Packit |
961e70 |
else
|
|
Packit |
961e70 |
p_child = p_del_item->p_right;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* This assignment may modify the parent pointer of the nil node.
|
|
Packit |
961e70 |
* This is inconsequential.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
p_child->p_up = p_del_item->p_up;
|
|
Packit |
961e70 |
(*__cl_map_get_parent_ptr_to_item( p_del_item )) = p_child;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if( p_del_item->color != CL_MAP_RED )
|
|
Packit |
961e70 |
__cl_map_del_bal( p_map, p_child );
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Note that the splicing done below does not need to occur before
|
|
Packit |
961e70 |
* the tree is balanced, since the actual topology changes are made by the
|
|
Packit |
961e70 |
* preceding code. The topology is preserved by the color assignment made
|
|
Packit |
961e70 |
* below (reader should be reminded that p_del_item == p_item in some cases).
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
if( p_del_item != p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Finalize the removal of the specified item by exchanging it with
|
|
Packit |
961e70 |
* the substitute which we removed above.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
p_del_item->p_up = p_item->p_up;
|
|
Packit |
961e70 |
p_del_item->p_left = p_item->p_left;
|
|
Packit |
961e70 |
p_del_item->p_right = p_item->p_right;
|
|
Packit |
961e70 |
(*__cl_map_get_parent_ptr_to_item( p_item )) = p_del_item;
|
|
Packit |
961e70 |
p_item->p_right->p_up = p_del_item;
|
|
Packit |
961e70 |
p_item->p_left->p_up = p_del_item;
|
|
Packit |
961e70 |
p_del_item->color = p_item->color;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map->nil_item->color != CL_MAP_RED );
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static cl_map_item_t *
|
|
Packit |
961e70 |
ips_cl_qmap_successor(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN const cl_map_item_t* p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t *p_tmp;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
p_tmp = p_item->p_right;
|
|
Packit |
961e70 |
if (p_tmp != p_map->nil_item) {
|
|
Packit |
961e70 |
while (p_tmp->p_left != p_map->nil_item)
|
|
Packit |
961e70 |
p_tmp = p_tmp->p_left;
|
|
Packit |
961e70 |
return p_tmp;
|
|
Packit |
961e70 |
} else {
|
|
Packit |
961e70 |
p_tmp = p_item->p_up;
|
|
Packit |
961e70 |
while (p_tmp->p_right == p_item) {
|
|
Packit |
961e70 |
p_item = p_tmp;
|
|
Packit |
961e70 |
p_tmp = p_tmp->p_up;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
if (p_tmp == p_map->root)
|
|
Packit |
961e70 |
return p_map->nil_item;
|
|
Packit |
961e70 |
return p_tmp;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit Service |
7ed5cc |
// When includer defines RBTREE_CMP, ips_cl_qmap_search() is not emitted.
|
|
Packit Service |
7ed5cc |
// When this happens, ips_cl_qmap_predecessor() may not be called.
|
|
Packit Service |
7ed5cc |
// Combined with -Werror -Wunused-function, libpsm2 fails to build.
|
|
Packit Service |
7ed5cc |
// So provide macro to control emitting this function
|
|
Packit Service |
7ed5cc |
#ifndef RBTREE_NO_EMIT_IPS_CL_QMAP_PREDECESSOR
|
|
Packit |
961e70 |
static cl_map_item_t *
|
|
Packit |
961e70 |
ips_cl_qmap_predecessor(
|
|
Packit |
961e70 |
IN cl_qmap_t* const p_map,
|
|
Packit |
961e70 |
IN const cl_map_item_t* p_item )
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t *p_tmp;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
p_tmp = p_item->p_left;
|
|
Packit |
961e70 |
if (p_tmp != p_map->nil_item) {
|
|
Packit |
961e70 |
while (p_tmp->p_right != p_map->nil_item)
|
|
Packit |
961e70 |
p_tmp = p_tmp->p_right;
|
|
Packit |
961e70 |
return p_tmp;
|
|
Packit |
961e70 |
} else {
|
|
Packit |
961e70 |
p_tmp = p_item->p_up;
|
|
Packit |
961e70 |
while (p_tmp->p_left == p_item) {
|
|
Packit |
961e70 |
p_item = p_tmp;
|
|
Packit |
961e70 |
p_tmp = p_tmp->p_up;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
if (p_tmp == p_map->root)
|
|
Packit |
961e70 |
return p_map->nil_item;
|
|
Packit |
961e70 |
return p_tmp;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
}
|
|
Packit Service |
7ed5cc |
#endif /* RBTREE_NO_EMIT_IPS_CL_QMAP_PREDECESSOR */
|
|
Packit |
961e70 |
|
|
Packit Service |
7ed5cc |
#if defined(RBTREE_GET_LEFTMOST)
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* return the first node with buffer overlapping or zero.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static cl_map_item_t *
|
|
Packit |
961e70 |
ips_cl_qmap_search(cl_qmap_t * const p_map,
|
|
Packit |
961e70 |
unsigned long start, unsigned long end)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
cl_map_item_t *p_item, *p_tmp;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
RBTREE_ASSERT( p_map );
|
|
Packit |
961e70 |
p_item = __cl_map_root(p_map);
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
while (p_item != p_map->nil_item) {
|
|
Packit |
961e70 |
if (start > RBTREE_GET_LEFTMOST(&p_item->payload)) {
|
|
Packit |
961e70 |
p_tmp = p_item->p_right;
|
|
Packit |
961e70 |
if (p_tmp != p_map->nil_item) {
|
|
Packit |
961e70 |
p_item = p_tmp;
|
|
Packit |
961e70 |
continue;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* p_item is on immediate left side of 'start'.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
if (start >= RBTREE_GET_RIGHTMOST(&p_item->payload)) {
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* p_item is on immediate right
|
|
Packit |
961e70 |
* side of 'start'.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
p_item = ips_cl_qmap_successor(p_map, p_item);
|
|
Packit |
961e70 |
if (p_item != p_map->nil_item &&
|
|
Packit |
961e70 |
end <= RBTREE_GET_LEFTMOST(&p_item->payload))
|
|
Packit |
961e70 |
p_item = p_map->nil_item;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
} else if (start < RBTREE_GET_LEFTMOST(&p_item->payload)) {
|
|
Packit |
961e70 |
p_tmp = p_item->p_left;
|
|
Packit |
961e70 |
if (p_tmp != p_map->nil_item) {
|
|
Packit |
961e70 |
p_item = p_tmp;
|
|
Packit |
961e70 |
continue;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* p_tmp is on immediate left side of 'start'.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
p_tmp = ips_cl_qmap_predecessor(p_map, p_item);
|
|
Packit |
961e70 |
if (p_tmp == p_map->nil_item ||
|
|
Packit |
961e70 |
(start >= RBTREE_GET_RIGHTMOST(&p_tmp->payload))) {
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* p_item is on immediate right
|
|
Packit |
961e70 |
* side of 'start'.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
if (end <= RBTREE_GET_LEFTMOST(&p_item->payload))
|
|
Packit |
961e70 |
p_item = p_map->nil_item;
|
|
Packit |
961e70 |
} else
|
|
Packit |
961e70 |
p_item = p_tmp;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
break;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
return p_item;
|
|
Packit |
961e70 |
}
|
|
Packit Service |
7ed5cc |
#else /* defined(...LEFTMOST) || defined(...RIGHTMOST) */
|
|
Packit Service |
7ed5cc |
static cl_map_item_t *
|
|
Packit Service |
7ed5cc |
ips_cl_qmap_searchv(cl_qmap_t * const p_map, const RBTREE_MI_PL *key)
|
|
Packit Service |
7ed5cc |
{
|
|
Packit Service |
7ed5cc |
RBTREE_ASSERT( p_map );
|
|
Packit Service |
7ed5cc |
cl_map_item_t *p_item = __cl_map_root(p_map);
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
while (p_item != p_map->nil_item) {
|
|
Packit Service |
7ed5cc |
if (RBTREE_CMP(key, &p_item->payload) > 0) {
|
|
Packit Service |
7ed5cc |
p_item = p_item->p_right;
|
|
Packit Service |
7ed5cc |
} else if (RBTREE_CMP(key, &p_item->payload) < 0) {
|
|
Packit Service |
7ed5cc |
p_item = p_item->p_left;
|
|
Packit Service |
7ed5cc |
} else {
|
|
Packit Service |
7ed5cc |
break;
|
|
Packit Service |
7ed5cc |
}
|
|
Packit Service |
7ed5cc |
}
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
return p_item;
|
|
Packit Service |
7ed5cc |
}
|
|
Packit Service |
7ed5cc |
#endif /* defined(...LEFTMOST) || defined(...RIGHTMOST) */
|