Files
mars-nwe/include/nwnss/library/rbpTree.h

231 lines
7.0 KiB
C

/****************************************************************************
|
| (C) Copyright 2003 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program 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 General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (PSS) Initialization module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| This module is used to: header file for red-black trees.
+-------------------------------------------------------------------------*/
/*
* Red-Black Tree Algorithm
*
* Cormen, Thomas H. [et al], "Introduction to Algorithms, 2nd Ed."
* MIT Press, McGraw-Hill, 2001, pp 273-301.
*
* Also see: Sedgweick, Robert, "Algorithms, 2nd Ed."
* Addison-Wesley, 1988, pp 215-230.
*
* Read-Black Tree Rules:
* 1. Every node is either red or black
* 2. The root is black
* 3. Every nil leaf is black
* 4. If a node is red, the both its children are black
* 5. For each node, all paths form the node to descendant
* leaves contain the same number of black nodes.
*
* I use the prefix "RBP_" to indicate Red-Black tree with a Parent pointer.
* RBP - for functions to be called by user.
* rbp - for internal functions used by algorithm
* rbp - to prefix field names.
*
* The RBP_Tree_s structure defines the type of the red-black tree. This
* lets one tree type be associated with multiple roots. This means that
* both the tree (type) and the root are passed to the tree manipulation
* routines.
*
* To make life simpler, if the root of the tree is set to NULL, the code
* will handle the real initialization of the tree. Also, if the root is
* ever set back to NIL, the code changes it to NULL. This allows for a
* simple test to check if the tree is empty.
*
* SMP Issue: Because the nil node in the RBP_Tree_s structure can be
* modified temporarily during delete operations, you must have separate
* RBP_Tree_s for each tree that can be updated independently.
*
*
* RBP_Init Initialize a red-black tree.
*
* tree: Pointer to type of tree being initialized
*
* nodeCompare: Compare two nodes. The node pointers have been
* adjusted to point to the beginning of the structure.
* If the first node is less then the second node, return
* a negative number. If equal, return 0. If greater
* than, return a positive number.
*
* keyCompare: Compare a node to a key. Note: a pointer to the key
* is passed.
*
* destroyNode: Routine to destroy the type of node stored in this tree.
*
* dumpNode: A routine to print the contents of a node. Used by
* debugging and auditing routines.
*
* offset: Because the user supplies the nodes imbedded in
* structures, this give the offset into the structure
* for the node. The above functions are called with
* structure pointer at the beginning of the structure.
*
*
* RBP_Insert Insert a node into the tree. Because we know the offset
* of the red-black node structure, you just pass in a
* pointer to the beginning of the user structure.
*
* tree: Pointer to tree type.
*
* proot: Pointer to a pointer to the root node for tree. The
* insert operation can change which node is at the root
* of the tree.
*
* node: User node to inserted to the tree. All key fields must
* be filled in. Note: node is a pointer to the beginning
* of the sturcture, not the RBP_Node_s field in the structure.
*
*
*/
#ifndef _RBPTREE_H_
#define _RBPTREE_H_
#ifndef _OMNI_H_
#include <omni.h>
#endif
typedef struct RBP_Node_s RBP_Node_s;
struct RBP_Node_s {
RBP_Node_s *p; /* Parent of node */
RBP_Node_s *l; /* Left child */
RBP_Node_s *r; /* Right child */
BOOL red; /* Color */
};
typedef struct RBP_Tree_s
{
NINT rbpOffset; /* Offset of node in structure */
SNINT (*rbpNodeCompare)( /* x < y --> - */
void *x, /* x == y --> 0 */
void *y); /* x > y --> + */
SNINT (*rbpKeyCompare)( /* key < x.key --> - */
void *key, /* key == x.key --> 0 */
void *x); /* key > x.key --> + */
BOOL (*rbpDestroyNode)(
void *x);
BOOL (*rbpDumpNode)( /* Print the given node */
void *x,
NINT depth,
ADDR msg); /* Why node is being dumped */
RBP_Node_s rbpNil;
#if NSS_DEBUG IS_ENABLED
NINT rbpInserts;
NINT rbpDeletes;
NINT rbpLeftRotates;
NINT rbpRightRotates;
#endif
} RBP_Tree_s;
/*
* Audits can be used to debug and track down errors in red-black trees,
*/
enum { MAX_DEPTH = 32 };
typedef struct RBP_Audit_s
{
NINT nodes;
void *maxNode;
NINT both;
NINT right;
NINT left;
NINT none;
NINT veryDeep;
NINT maxDepth;
NINT redNodes;
NINT blackNodes;
NINT depth[MAX_DEPTH];
NINT red[MAX_DEPTH];
NINT black[MAX_DEPTH];
} RBP_Audit_s;
#define RBP_INIT_TREE(_tree, _nodeCompare, _keyCompare, _destroyNode, \
_dumpNode, _offset) \
{ \
(_offset), (_nodeCompare), (_keyCompare), (_destroyNode), (_dumpNode), \
{ &(_tree).rbpNil, &(_tree).rbpNil, &(_tree).rbpNil, FALSE } \
}
extern void RBP_Init(
RBP_Tree_s *tree,
SNINT (*nodeCompare)(),
SNINT (*keyCompare)(),
BOOL (*destroyNode)(),
BOOL (*dumpNode)(),
NINT offset);
extern void RBP_Insert(RBP_Tree_s *tree, RBP_Node_s **proot, void *node);
extern void RBP_Delete(RBP_Tree_s *tree, RBP_Node_s **proot, void *node);
extern void *RBP_Find(RBP_Tree_s *tree, RBP_Node_s *root, void *key);
extern void *RBP_FindCeiling(RBP_Tree_s *tree, RBP_Node_s *root, void *key);
extern void *RBP_FindFloor(RBP_Tree_s *tree, RBP_Node_s *root, void *key);
extern void *RBP_Min(RBP_Tree_s *tree, RBP_Node_s *root);
extern void *RBP_Max(RBP_Tree_s *tree, RBP_Node_s *root);
extern void *RBP_Succ(RBP_Tree_s *tree, void *node);
extern void *RBP_Pred(RBP_Tree_s *tree, void *node);
extern void RBP_Audit(RBP_Tree_s *tree, RBP_Node_s *root, RBP_Audit_s *audit);
extern void RBP_InOrder(
RBP_Tree_s *tree,
RBP_Node_s *root,
BOOL (*userFunc)(
void *node,
NINT depth,
ADDR userData),
ADDR userData);
extern void RBP_PostOrder(
RBP_Tree_s *tree,
RBP_Node_s *root,
BOOL (*userFunc)(
void *node,
NINT depth,
ADDR userData),
ADDR userData);
extern void RBP_DestroyTree(RBP_Tree_s *tree, RBP_Node_s **proot);
#endif