Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

461 lines
9.0 KiB

/* --------------------------------------------------------------------
Microsoft OS/2 LAN Manager
Copyright(c) Microsoft Corp., 1990
RPC - Written by Dov Harel
This file contains the implementation for splay tree self
adjusting binary trees
-------------------------------------------------------------------- */
#include <dict.hxx>
// handly macros used to define common tree operations
#define ROTATELEFT tmp=t->right; t->right=tmp->left; tmp->left =t; t=tmp
#define ROTATERIGHT tmp=t->left; t->left =tmp->right; tmp->right=t; t=tmp
#define LINKLEFT tmp=t; t = t->right; l = l->right = tmp
#define LINKRIGHT tmp=t; t = t->left; r = r->left = tmp
#define ASSEMBLE r->left = t->right; l->right = t->left; \
t->left = Dummy->right; t->right = Dummy->left
static TreeNode Dumbo(Nil);
static TreeNode *Dummy = &Dumbo; // a global dummy node
#ifndef RUNTIME
/**
extern "C" {
void printf();
}
**/
#define DICT_NOPREV
#define DICT_NONEXT
#define DICT_NOPRINT
#else
extern "C"
void printf(void *, ...);
#endif
//*************************************************************************
//***** Core functions (internal) *****
//*************************************************************************
int // return last comparision
Dictionary::SplayUserType( // general top down splay
pUserType keyItem // pointer to a "key item" searched for
) //-----------------------------------------------------------------------//
{
TreeNode* t; // current search point
TreeNode* l; // root of "left subtree" < keyItem
TreeNode* r; // root of "right subtree" > keyItem
int kcmp; // cash comparison results
TreeNode* tmp;
if ((fCompare = CompareItem(keyItem, root->item)) == 0)
return (fCompare);
Dummy = l = r = &Dumbo;
Dumbo.left = Dumbo.right = Nil;
t = root;
do {
if ( fCompare < 0 ) {
if ( t->left == Nil ) break;
if ( (kcmp = CompareItem(keyItem, t->left->item)) == 0 ) {
LINKRIGHT;
}
else if ( kcmp < 0 ) {
ROTATERIGHT;
if ( t->left != Nil ) {
LINKRIGHT;
}
}
else { // keyItem > t->left->item
LINKRIGHT;
if ( t->right != Nil ) {
LINKLEFT;
}
}
}
else { // keyItem > t->item
if ( t->right == Nil ) break;
if ( (kcmp = CompareItem(keyItem, t->right->item)) == 0 ) {
LINKLEFT;
}
else if ( kcmp > 0 ) {
ROTATELEFT;
if ( t->right != Nil ) {
LINKLEFT;
}
}
else { // keyItem < t->right->item
LINKLEFT;
if ( t->left != Nil ) {
LINKRIGHT;
}
}
}
} while ( (fCompare = CompareItem(keyItem, t->item)) != 0 );
ASSEMBLE;
// if (fCompare != CompareItem(keyItem, t->item))
// printf("Dictionary error!");
root = t;
return(fCompare);
}
TreeNode*
SplayLeft(
TreeNode* t // root of tree & current "search" point
) //-----------------------------------------------------------------------//
{
TreeNode* l=Dummy; // root of "left subtree" < keyItem
TreeNode* r=Dummy; // root of "right subtree" > keyItem
TreeNode* tmp;
if (t == Nil || t->left == Nil)
return(t);
if (t->left->left == Nil) {
ROTATERIGHT;
return(t);
}
Dummy->left = Dummy->right = Nil;
while ( t->left != Nil ) {
ROTATERIGHT;
if ( t->left != Nil ) {
LINKRIGHT;
}
}
ASSEMBLE;
return(t);
}
#ifndef DICT_NOPREV
TreeNode*
SplayRight(
TreeNode* t // root of tree & current "search" point
) //-----------------------------------------------------------------------//
{
TreeNode* l=Dummy; // root of "left subtree" < keyItem
TreeNode* r=Dummy; // root of "right subtree" > keyItem
TreeNode* tmp;
if (t == Nil || t->right == Nil)
return(t);
Dummy->left = Dummy->right = Nil;
while ( t->right != Nil ) {
ROTATELEFT;
if ( t->right != Nil ) {
LINKLEFT;
}
}
ASSEMBLE;
return(t);
}
#endif
// Class methods for Splay Tree
Dict_Status
Dictionary::Dict_Find( // return a item that matches
pUserType itemI // this value
// Returns:
// itemCur - Nil if at not in Dict, else found item
) //-----------------------------------------------------------------------//
{
itemCur = Nil;
if (root == Nil)
return (EMPTY_DICTIONARY);
if (itemI == Nil)
return (NULL_ITEM);
if (SplayUserType (itemI) == 0){
itemCur = root->item;
return(SUCCESS);
}
// printf("After NotFound %ld: (", this); PrintItem(itemI); printf(")\n"); Dict_Print();
return(ITEM_NOT_FOUND);
}
#ifndef DICT_NONEXT
Dict_Status
Dictionary::Dict_Next( // return the next item
pUserType itemI // of a key greater then this
// Returns:
// itemCur - Nil if at end of Dict, else current item
) //-----------------------------------------------------------------------//
{
TreeNode* t;
itemCur = Nil;
if (root == Nil)
return (EMPTY_DICTIONARY);
if (itemI == Nil) { // no arg, return first record
root = SplayLeft (root);
itemCur = root->item;
return (SUCCESS);
}
if (itemI != root->item)
if (SplayUserType (itemI) > 0) {
itemCur = root->item;
return (SUCCESS);
}
if (root->right == Nil)
return (LAST_ITEM);
t = root;
root = SplayLeft (root->right);
root->left = t;
t->right = Nil;
itemCur = root->item;
return (SUCCESS);
}
#endif // DICT_NONEXT
#ifndef DICT_NOPREV
Dict_Status
Dictionary::Dict_Prev( // return the previous item
pUserType itemI // of a key less then this
// Returns:
// itemCur - Nil if at begining of Dict, else current item
) //-----------------------------------------------------------------------//
{
TreeNode* t;
itemCur = Nil;
if (root == Nil)
return (EMPTY_DICTIONARY);
if (itemI == Nil) { // no arg, return last record
root = SplayRight (root);
itemCur = root->item;
return (SUCCESS);
}
if (itemI != root->item)
if (SplayUserType (itemI) < 0) {
itemCur = root->item;
return (SUCCESS);
}
if (root->left == Nil)
return (LAST_ITEM);
t = root;
root = SplayRight (root->left);
root->right = t;
t->left = Nil;
itemCur = root->item;
return (SUCCESS);
}
#endif // DICT_NOPREV
Dict_Status
Dictionary::Dict_Insert(
pUserType itemI,
pUserType key
)
{
TreeNode *newNode, *t;
if ((itemCur = itemI) == Nil)
return (NULL_ITEM);
if (root == Nil) {
root = new TreeNode(itemI);
if (!root)
return(OUT_OF_MEMORY);
size++;
return (SUCCESS);
}
if (SplayUserType (key) == 0)
return (ITEM_ALREADY_PRESENT);
newNode = new TreeNode(itemI);
if (!root)
return(OUT_OF_MEMORY);
size++;
t = root;
if (fCompare > 0) {
newNode->right = t->right; // item >= t->item
newNode->left = t;
t->right = Nil;
}
else {
newNode->left = t->left;
newNode->right = t;
t->left = Nil;
}
root = newNode;
// printf("After Insert %ld: (", this); PrintItem(itemI); printf(")\n"); Dict_Print();
return (SUCCESS);
}
Dict_Status
Dictionary::Dict_Delete( // delete the given item from the tree
pUserType *itemI // points to the (key) item to be deleted
// Returns:
// itemCur is Nil - undefined
) //-----------------------------------------------------------------------//
{
TreeNode *t, *r;
itemCur = Nil;
if (root == Nil)
return (EMPTY_DICTIONARY);
if (itemI == Nil)
return (NULL_ITEM);
if (itemI != root->item) {
if (SplayUserType (*itemI) != 0)
return(ITEM_NOT_FOUND);
}
*itemI = root->item;
t = root;
if (t->left == Nil)
root = t->right;
else if ( (r = t->right) == Nil)
root = t->left;
else {
r = SplayLeft (r);
r->left = t->left; // at this point r->left == Nil
root = r;
}
delete t;
size--;
return (SUCCESS);
}
// Utility functions to print of a tree
#ifndef DICT_NOPRINT
static indentCur;
static PrintFN printCur;
static char spaces[] =
" ";
void
prinTree( // recursively print out a tree
int lmargin, // current depth & margen
TreeNode *np // subtree to print
) //-----------------------------------------------------------------------//
{
if (np == Nil)
return;
prinTree(lmargin+indentCur, np->right);
if (lmargin > sizeof(spaces))
lmargin = sizeof(spaces);;
spaces[lmargin] = 0;
printf(spaces);
spaces[lmargin] = ' ';
(*printCur)(np->item);
printf("\n");
prinTree(lmargin+indentCur, np->left);
}
void
Dictionary::Dict_Print(
int indent
// prints the binary tree (indented right subtree,
// followed by the root, followed by the indented right dubtree)
) //-----------------------------------------------------------------------//
{
indentCur = indent;
if ((printCur = PrintItem) == Nil){
printf("Dictionary::Print - no print function defined in constructor");
return;
}
prinTree(0, root);
}
#endif // DICT_PRINT