231 lines
7.0 KiB
C
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
|