One leftover from sync

svn path=/branches/reactos-yarotows/; revision=48247
This commit is contained in:
Jérôme Gardou 2010-07-25 11:19:21 +00:00
parent 82822656c3
commit 7bb96de441
6 changed files with 0 additions and 967 deletions

View file

@ -1,434 +0,0 @@
/*
* Austin---Astonishing Universal Search Tree Interface Novelty
* Copyright (C) 2000 Kaz Kylheku <kaz@ashi.footprints.net>
* Copyright (C) 2000 Carl van Tast <vanTast@netway.at>
*
* Free Software License:
*
* All rights are reserved by the author, with the following exceptions:
* Permission is granted to freely reproduce and distribute this software,
* possibly in exchange for a fee, provided that this copyright notice appears
* intact. Permission is also granted to adapt this software to produce
* derivative works, as long as the modified versions carry this copyright
* notice and additional notices stating that the work has been modified.
* This source code may be translated into executable form and incorporated
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
* $Id: avl.c,v 1.3 2000/01/12 02:37:02 kaz Exp $
* $Name: austin_0_2 $
*/
/*
* Modified for use in ReactOS by arty
*/
#include "rtl.h"
#include "udict.h"
#include "tree.h"
#include "macros.h"
#define balance Balance
#define BALANCED udict_balanced
#define LEFTHEAVY udict_leftheavy
#define RIGHTHEAVY udict_rightheavy
#define EQUAL GenericEqual
#define LESS GenericLessThan
#define GREATER GenericGreaterThan
int print_node(udict_t *ud, udict_node_t *node, int indent)
{
int i, rh = 0, lh = 0;
char buf[100];
udict_node_t *nil = ud->BalancedRoot.Parent;
for( i = 0; i < indent; i++ ) buf[i] = ' ';
if( node == ud->BalancedRoot.Parent ) {
sprintf(buf+i, "Nil\n");
DbgPrint("%s", buf);
return 0;
} else {
sprintf(buf+i, "Node %p (parent %p: balance %d)\n", node, node->parent, node->Balance);
DbgPrint("%s", buf);
if( node->LeftChild != nil ) {
sprintf(buf+i, "--> Left\n");
DbgPrint("%s", buf);
lh = print_node(ud, node->LeftChild, indent+1);
}
if( node->RightChild != nil ) {
sprintf(buf+i, "--> Right\n");
DbgPrint("%s", buf);
rh = print_node(ud, node->RightChild, indent+1);
}
if (indent)
{
if (rh < lh - 1 || lh < rh - 1)
{
sprintf(buf+i, "warning: tree is too unbalanced %d vs %d\n",
lh, rh);
DbgPrint("%s", buf);
}
if (rh != lh && node->Balance == BALANCED)
{
sprintf(buf+i, "warning: tree says balanced, but %d vs %d\n",
lh, rh);
DbgPrint("%s", buf);
}
else if (lh <= rh && node->Balance == LEFTHEAVY)
{
sprintf(buf+i, "warning: tree says leftheavy but %d vs %d\n",
lh, rh);
DbgPrint("%s", buf);
}
else if (lh >= rh && node->Balance == RIGHTHEAVY)
{
sprintf(buf+i, "warning: tree says rightheavy but %d vs %d\n",
lh, rh);
DbgPrint("%s", buf);
}
}
if (rh > lh) return 1+rh;
else return 1+lh;
}
}
void print_tree(udict_t *ud)
{
DbgPrint("TREE %x (Nil %x)\n", ud, ud->BalancedRoot.Parent);
print_node(ud, &ud->BalancedRoot, 0);
}
void avl_init(udict_t *ud)
{
ud->BalancedRoot.left = ud->BalancedRoot.right =
ud->BalancedRoot.parent = (udict_node_t*)
ud->AllocateRoutine(ud, sizeof(udict_node_t));
ud->BalancedRoot.parent->left = ud->BalancedRoot.parent->right =
ud->BalancedRoot.parent->parent = ud->BalancedRoot.parent;
}
void avl_deinit(udict_t *ud)
{
ud->FreeRoutine(ud, ud->BalancedRoot.parent);
}
static void RotateLeft(udict_node_t **top)
{
udict_node_t *parent = *top;
udict_node_t *child = parent->right;
child->parent = parent->parent;
parent->right = child->left;
parent->right->parent = parent; /* may change sentinel.parent */
child->left = parent;
parent->parent = child;
*top = child;
}/*RotateLeft*/
static void RotateRight(udict_node_t **top)
{
udict_node_t *parent = *top;
udict_node_t *child = parent->left;
child->parent = parent->parent;
parent->left = child->right;
parent->left->parent = parent; /* may change sentinel.parent */
child->right = parent;
parent->parent = child;
*top = child;
}/*RotateRight*/
static void FixBalance(udict_node_t **pnode, udict_avl_balance_t bal)
{
udict_node_t *node = *pnode;
udict_node_t *child;
udict_node_t *grandchild;
if (node->balance == BALANCED) {
node->balance = bal;
}/*if*/
else if (node->balance != bal) {
node->balance = BALANCED;
}/*elsif*/
else {
assert (node->balance == bal);
if (bal == LEFTHEAVY) {
child = node->left;
if (child->balance == LEFTHEAVY) {
node->balance = BALANCED;
child->balance = BALANCED;
RotateRight(pnode);
}/*if*/
else if (child->balance == BALANCED) {
/* only possible after delete */
node->balance = LEFTHEAVY;
child->balance = RIGHTHEAVY;
RotateRight(pnode);
}/*elsif*/
else {
assert (child->balance == RIGHTHEAVY);
grandchild = child->right;
if (grandchild->balance == LEFTHEAVY) {
node->balance = RIGHTHEAVY;
child->balance = BALANCED;
}/*if*/
else if (grandchild->balance == RIGHTHEAVY) {
node->balance = BALANCED;
child->balance = LEFTHEAVY;
}/*elsif*/
else {
node->balance = BALANCED;
child->balance = BALANCED;
}/*else*/
grandchild->balance = BALANCED;
RotateLeft(&node->left);
RotateRight(pnode);
}/*else*/
}/*if*/
else {
assert (bal == RIGHTHEAVY);
child = node->right;
if (child->balance == RIGHTHEAVY) {
node->balance = BALANCED;
child->balance = BALANCED;
RotateLeft(pnode);
}/*if*/
else if (child->balance == BALANCED) {
/* only possible after delete */
node->balance = RIGHTHEAVY;
child->balance = LEFTHEAVY;
RotateLeft(pnode);
}/*elsif*/
else {
assert (child->balance == LEFTHEAVY);
grandchild = child->left;
if (grandchild->balance == RIGHTHEAVY) {
node->balance = LEFTHEAVY;
child->balance = BALANCED;
}/*if*/
else if (grandchild->balance == LEFTHEAVY) {
node->balance = BALANCED;
child->balance = RIGHTHEAVY;
}/*elsif*/
else {
node->balance = BALANCED;
child->balance = BALANCED;
}/*else*/
grandchild->balance = BALANCED;
RotateRight(&node->right);
RotateLeft(pnode);
}/*else*/
}/*else*/
}/*else*/
}/*FixBalance*/
static int Insert(udict_t *ud, udict_node_t *what, udict_node_t **where, udict_node_t *parent)
{
udict_node_t *here = *where;
int result;
if (here == tree_null_priv(ud)) {
*where = what;
what->parent = parent;
return 1; /* higher than before */
}/*if*/
else {
result = ud->compare(ud, key(what), key(here));
assert (result != GenericEqual);
if (result == LESS) {
if (Insert(ud, what, &here->left, here)) {
/*
** now left side is higher than before
*/
FixBalance(where, LEFTHEAVY);
return ((*where)->balance != BALANCED);
}/*if*/
}/*if*/
else {
if (Insert(ud, what, &here->right, here)) {
/*
** now right side is higher than before
*/
FixBalance(where, RIGHTHEAVY);
return ((*where)->balance != BALANCED);
}/*if*/
}/*else*/
}/*else*/
return 0; /* height not changed */
}/*Insert*/
void avl_insert_node(udict_t *ud, udict_node_t *node)
{
udict_node_t *nil = tree_null_priv(ud);
node->left = nil;
node->right = nil;
node->balance = BALANCED;
if (Insert(ud, node, &ud->BalancedRoot.left, nil)) {
nil->balance = LEFTHEAVY;
}/*if*/
if (ud->BalancedRoot.left == node) {
node->parent = &ud->BalancedRoot;
ud->BalancedRoot.balance = LEFTHEAVY;
}
ud->nodecount++;
}
void avl_delete_node(udict_t *ud, udict_node_t *node)
{
udict_node_t *nil = tree_null_priv(ud);
udict_node_t *swap;
udict_node_t *child;
udict_node_t *parent;
udict_tree_delete(ud, node, &swap, &child);
#ifndef NDEBUG
if (swap == node) {
/*
** node had 0 or 1 child,
** child moved up to node's place
*/
if (child != nil) {
assert ((child->left == nil) && (child->right == nil));
assert (child->balance == BALANCED);
}/*if*/
}/*if*/
else {
/*
** node had 2 children,
** swap was node's successor (in node's right subtree),
** swap has been inserted in node's place,
** child was swap->right,
** child has been moved to swap's place
*/
if (child != nil) {
assert ((child->left == nil) && (child->right == nil));
assert (child->balance == BALANCED);
}/*if*/
}/*else*/
#endif
swap->balance = node->balance;
/*
** In either case, child has been moved to the next higher level.
** So the balance of its new parent has to be checked.
** Note, that child->parent points to the node we are interested in,
** even if child == nil.
*/
parent = child->parent;
if (parent == nil) {
/* root has been deleted */
if (child == nil) {
parent->balance = BALANCED;
ud->BalancedRoot.left = nil;
}/*if*/
}/*if*/
while (parent != &ud->BalancedRoot) {
if ((parent->left == nil) && (parent->right == nil)) {
assert (child == nil);
parent->balance = BALANCED;
/* propagate height reduction to upper level */
}/*if*/
else {
udict_node_t **pparent;
if (parent == parent->parent->left)
pparent = &parent->parent->left;
else
pparent = &parent->parent->right;
if (child == parent->left) {
/* reduce parent's left height */
FixBalance(pparent, RIGHTHEAVY);
}/*if*/
else {
assert (child == parent->right);
/* reduce parent's right height */
FixBalance(pparent, LEFTHEAVY);
}/*else*/
/*
** parent and child are not valid now,
** pparent may point to new root of subtree
*/
parent = *pparent;
}/*else*/
/* if subtree is balanced, then height is less than before */
if (parent->balance == BALANCED) {
child = parent;
parent = child->parent;
}/*if*/
else
break;
}/*while*/
}/*avl_delete_node*/
void *avl_get_data(udict_node_t *here) {
return data(here);
}
int avl_search(udict_t *ud, void *_key, udict_node_t *here, udict_node_t **where)
{
int result;
if (avl_is_nil(ud, here))
return TableInsertAsLeft;
result = ud->compare(ud, _key, key(here));
if (result == EQUAL) {
*where = here;
return TableFoundNode;
}
if (result == LESS) {
if( here->left == tree_null_priv(ud) ) {
*where = here;
return TableInsertAsLeft;
}
return avl_search(ud, _key, here->left, where);
}/*if*/
else {
if( here->right == tree_null_priv(ud) ) {
*where = here;
return TableInsertAsRight;
}
return avl_search(ud, _key, here->right, where);
}/*else*/
}
int avl_is_nil(udict_t *ud, udict_node_t *node)
{
return tree_null_priv(ud) == node ||
&ud->BalancedRoot == node;
}
udict_node_t *avl_first(udict_t *ud)
{
return udict_tree_first(ud);
}
udict_node_t *avl_last(udict_t *ud)
{
return udict_tree_last(ud);
}
udict_node_t *avl_next(udict_t *ud, udict_node_t *prev)
{
udict_node_t *node = udict_tree_next(ud, prev);
if( node == tree_null_priv(ud) || node == &ud->BalancedRoot )
return NULL;
else
return node;
}

View file

@ -1,26 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS System Libraries
* FILE: lib/rtl/austin/avl.h
* PURPOSE: Run-Time Libary Header (interface to austin AVL tree)
* PROGRAMMER: arty
*/
#pragma once
#define avl_data(x) ((void*)(&(x)[1]))
void avl_init(PRTL_AVL_TABLE table);
void avl_deinit(PRTL_AVL_TABLE table);
void avl_insert_node(PRTL_AVL_TABLE table, PRTL_BALANCED_LINKS node);
void avl_delete_node(PRTL_AVL_TABLE table, PRTL_BALANCED_LINKS node);
int avl_is_nil(PRTL_AVL_TABLE table, PRTL_BALANCED_LINKS node);
PRTL_BALANCED_LINKS avl_first(PRTL_AVL_TABLE table);
PRTL_BALANCED_LINKS avl_last(PRTL_AVL_TABLE table);
PRTL_BALANCED_LINKS avl_next(PRTL_AVL_TABLE table, PRTL_BALANCED_LINKS node);
int avl_search
(PRTL_AVL_TABLE table,
PVOID _key,
PRTL_BALANCED_LINKS node,
PRTL_BALANCED_LINKS *where);

View file

@ -1,51 +0,0 @@
/*
* Austin---Astonishing Universal Search Tree Interface Novelty
* Copyright (C) 2000 Kaz Kylheku <kaz@ashi.footprints.net>
*
* Free Software License:
*
* All rights are reserved by the author, with the following exceptions:
* Permission is granted to freely reproduce and distribute this software,
* possibly in exchange for a fee, provided that this copyright notice appears
* intact. Permission is also granted to adapt this software to produce
* derivative works, as long as the modified versions carry this copyright
* notice and additional notices stating that the work has been modified.
* This source code may be translated into executable form and incorporated
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
* $Id: macros.h,v 1.1 1999/11/26 05:59:49 kaz Exp $
* $Name: austin_0_2 $
*/
/*
* Modified for use in ReactOS by arty
*/
/*
* Macros which give short, convenient internal names to public structure
* members. These members have prefixed names to reduce the possiblity of
* clashes with foreign macros.
*/
#define left LeftChild
#define right RightChild
#define parent Parent
#define next RightChild
#define prev LeftChild
#define data(x) ((void *)&((x)[1]))
#define key(x) ((void *)&((x)[1]))
#define rb_color udict_rb_color
#define algo_specific udict_algo_specific
#define optable udict_optable
#define nodecount NumberGenericTableElements
#define maxcount udict_maxcount
#define dupes_allowed udict_dupes_allowed
#define sentinel BalancedRoot
#define compare CompareRoutine
#define nodealloc AllocateRoutine
#define nodefree FreeRoutine
#define context TableContext
#define assert(x) { if(!(x)) { RtlAssert(#x, __FILE__, __LINE__, NULL); } }

View file

@ -1,292 +0,0 @@
/*
* Austin---Astonishing Universal Search Tree Interface Novelty
* Copyright (C) 2000 Kaz Kylheku <kaz@ashi.footprints.net>
*
* Free Software License:
*
* All rights are reserved by the author, with the following exceptions:
* Permission is granted to freely reproduce and distribute this software,
* possibly in exchange for a fee, provided that this copyright notice appears
* intact. Permission is also granted to adapt this software to produce
* derivative works, as long as the modified versions carry this copyright
* notice and additional notices stating that the work has been modified.
* This source code may be translated into executable form and incorporated
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
* $Id: tree.c,v 1.8 1999/12/09 05:38:52 kaz Exp $
* $Name: austin_0_2 $
*/
/*
* Modified for use in ReactOS by arty
*/
#include "rtl.h"
#include "udict.h"
#include "tree.h"
#include "macros.h"
void udict_tree_delete(udict_t *ud, udict_node_t *node, udict_node_t **pswap, udict_node_t **pchild)
{
udict_node_t *nil = tree_null_priv(ud), *child, *delparent = node->parent;
udict_node_t *next = node, *nextparent;
if( tree_root_priv(ud) == node )
delparent = &ud->BalancedRoot;
if (node->left != nil && node->right != nil) {
next = udict_tree_next(ud, node);
nextparent = next->parent;
if( tree_root_priv(ud) == next )
nextparent = &ud->BalancedRoot;
assert (next != nil);
assert (next->parent != nil);
assert (next->left == nil);
/*
* First, splice out the successor from the tree completely, by
* moving up its right child into its place.
*/
child = next->right;
child->parent = nextparent;
if (nextparent->left == next) {
nextparent->left = child;
} else {
assert (nextparent->right == next);
nextparent->right = child;
}
/*
* Now that the successor has been extricated from the tree, install it
* in place of the node that we want deleted.
*/
next->parent = delparent;
next->left = node->left;
next->right = node->right;
next->left->parent = next;
next->right->parent = next;
if (delparent->left == node) {
delparent->left = next;
} else {
assert (delparent->right == node);
delparent->right = next;
}
} else {
assert (node != nil);
assert (node->left == nil || node->right == nil);
child = (node->left != nil) ? node->left : node->right;
child->parent = delparent = node->parent;
if (node == delparent->left) {
delparent->left = child;
} else {
assert (node == delparent->right);
delparent->right = child;
}
}
node->parent = nil;
node->right = nil;
node->left = nil;
ud->nodecount--;
*pswap = next;
*pchild = child;
}
udict_node_t *udict_tree_lookup(udict_t *ud, const void *_key)
{
udict_node_t *root = tree_root_priv(ud);
udict_node_t *nil = tree_null_priv(ud);
int result;
/* simple binary search adapted for trees that contain duplicate keys */
while (root != nil) {
result = ud->compare(ud, (void *)_key, key(root));
if (result < 0)
root = root->left;
else if (result > 0)
root = root->right;
else {
return root;
}
}
return 0;
}
udict_node_t *udict_tree_lower_bound(udict_t *ud, const void *_key)
{
udict_node_t *root = tree_root_priv(ud);
udict_node_t *nil = tree_null_priv(ud);
udict_node_t *tentative = 0;
while (root != nil) {
int result = ud->compare(ud, (void *)_key, key(root));
if (result > 0) {
root = root->right;
} else if (result < 0) {
tentative = root;
root = root->left;
} else {
return root;
}
}
return tentative;
}
udict_node_t *udict_tree_upper_bound(udict_t *ud, const void *_key)
{
udict_node_t *root = tree_root_priv(ud);
udict_node_t *nil = tree_null_priv(ud);
udict_node_t *tentative = 0;
while (root != nil) {
int result = ud->compare(ud, (void *)_key, key(root));
if (result < 0) {
root = root->left;
} else if (result > 0) {
tentative = root;
root = root->right;
} else {
return root;
}
}
return tentative;
}
udict_node_t *udict_tree_first(udict_t *ud)
{
udict_node_t *nil = tree_null_priv(ud), *root = tree_root_priv(ud), *left;
if (root != nil)
while ((left = root->left) != nil)
root = left;
return (root == nil) ? 0 : root;
}
udict_node_t *udict_tree_last(udict_t *ud)
{
udict_node_t *nil = tree_null_priv(ud), *root = tree_root_priv(ud), *right;
if (root != nil)
while ((right = root->right) != nil)
root = right;
return (root == nil) ? 0 : root;
}
udict_node_t *udict_tree_next(udict_t *ud, udict_node_t *curr)
{
udict_node_t *nil = tree_null_priv(ud), *parent, *left;
if (curr->right != nil) {
curr = curr->right;
while ((left = curr->left) != nil)
curr = left;
return curr;
}
parent = curr->parent;
while (parent != nil && curr == parent->right) {
curr = parent;
parent = curr->parent;
}
return (parent == nil) ? 0 : parent;
}
udict_node_t *udict_tree_prev(udict_t *ud, udict_node_t *curr)
{
udict_node_t *nil = tree_null_priv(ud), *parent, *right;
if (curr->left != nil) {
curr = curr->left;
while ((right = curr->right) != nil)
curr = right;
return curr;
}
parent = curr->parent;
while (parent != nil && curr == parent->left) {
curr = parent;
parent = curr->parent;
}
return (parent == nil) ? 0 : parent;
}
/*
* Perform a ``left rotation'' adjustment on the tree. The given parent node P
* and its right child C are rearranged so that the P instead becomes the left
* child of C. The left subtree of C is inherited as the new right subtree
* for P. The ordering of the keys within the tree is thus preserved.
*/
void udict_tree_rotate_left(udict_node_t *child, udict_node_t *parent)
{
udict_node_t *leftgrandchild, *grandpa;
assert (parent->right == child);
child = parent->right;
parent->right = leftgrandchild = child->left;
leftgrandchild->parent = parent;
child->parent = grandpa = parent->parent;
if (parent == grandpa->left) {
grandpa->left = child;
} else {
assert (parent == grandpa->right);
grandpa->right = child;
}
child->left = parent;
parent->parent = child;
}
/*
* This operation is the ``mirror'' image of rotate_left. It is
* the same procedure, but with left and right interchanged.
*/
void udict_tree_rotate_right(udict_node_t *child, udict_node_t *parent)
{
udict_node_t *rightgrandchild, *grandpa;
assert (parent->left == child);
parent->left = rightgrandchild = child->right;
rightgrandchild->parent = parent;
child->parent = grandpa = parent->parent;
if (parent == grandpa->right) {
grandpa->right = child;
} else {
assert (parent == grandpa->left);
grandpa->left = child;
}
child->right = parent;
parent->parent = child;
}

View file

@ -1,41 +0,0 @@
/*
* Austin---Astonishing Universal Search Tree Interface Novelty
* Copyright (C) 2000 Kaz Kylheku <kaz@ashi.footprints.net>
*
* Free Software License:
*
* All rights are reserved by the author, with the following exceptions:
* Permission is granted to freely reproduce and distribute this software,
* possibly in exchange for a fee, provided that this copyright notice appears
* intact. Permission is also granted to adapt this software to produce
* derivative works, as long as the modified versions carry this copyright
* notice and additional notices stating that the work has been modified.
* This source code may be translated into executable form and incorporated
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
* $Id: tree.h,v 1.5 1999/12/09 05:38:52 kaz Exp $
* $Name: austin_0_2 $
*/
/*
* Modified for use in ReactOS by arty
*/
void udict_tree_init(udict_t *ud);
void udict_tree_insert(udict_t *ud, udict_node_t *node, const void *key);
void udict_tree_delete(udict_t *, udict_node_t *, udict_node_t **, udict_node_t **);
udict_node_t *udict_tree_lookup(udict_t *, const void *);
udict_node_t *udict_tree_lower_bound(udict_t *, const void *);
udict_node_t *udict_tree_upper_bound(udict_t *, const void *);
udict_node_t *udict_tree_first(udict_t *);
udict_node_t *udict_tree_last(udict_t *);
udict_node_t *udict_tree_next(udict_t *, udict_node_t *);
udict_node_t *udict_tree_prev(udict_t *, udict_node_t *);
void udict_tree_convert_to_list(udict_t *);
void udict_tree_convert_from_list(udict_t *);
void udict_tree_rotate_left(udict_node_t *, udict_node_t *);
void udict_tree_rotate_right(udict_node_t *, udict_node_t *);
#define tree_root_priv(T) ((T)->BalancedRoot.left)
#define tree_null_priv(L) ((L)->BalancedRoot.parent)
#define TREE_DEPTH_MAX 64

View file

@ -1,123 +0,0 @@
/*
* Austin---Astonishing Universal Search Tree Interface Novelty
* Copyright (C) 2000 Kaz Kylheku <kaz@ashi.footprints.net>
*
* Free Software License:
*
* All rights are reserved by the author, with the following exceptions:
* Permission is granted to freely reproduce and distribute this software,
* possibly in exchange for a fee, provided that this copyright notice appears
* intact. Permission is also granted to adapt this software to produce
* derivative works, as long as the modified versions carry this copyright
* notice and additional notices stating that the work has been modified.
* This source code may be translated into executable form and incorporated
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
* $Id: udict.h,v 1.6 1999/12/09 07:32:48 kaz Exp $
* $Name: austin_0_2 $
*/
/*
* Modified for use in ReactOS by arty
*/
#pragma once
#include <limits.h>
#define WIN32_NO_STATUS
#define _INC_SWPRINTF_INL_
#include <windows.h>
#include <ndk/ntndk.h>
#include "avl.h"
#define UDICT_COUNT_T_MAX ULONG_MAX
typedef unsigned long udict_count_t;
typedef unsigned int udict_alg_id_t;
#define UDICT_LIST 0
#define UDICT_BST 1
#define UDICT_REDBLACK 2
#define UDICT_SPLAY 3
#define UDICT_AVL 4
typedef enum {
udict_bst,
udict_list,
udict_other
} udict_algkind_t;
typedef enum {
udict_red,
udict_black
} udict_rb_color_t;
typedef enum {
udict_balanced = 0,
udict_leftheavy = 1,
udict_rightheavy = 2
} udict_avl_balance_t;
typedef union {
int udict_dummy;
udict_rb_color_t udict_rb_color;
udict_avl_balance_t udict_avl_balance;
} udict_algdata_t;
typedef struct _RTL_BALANCED_LINKS udict_node_t;
typedef int (*udict_compare_t)(const void *, const void *);
typedef udict_node_t *(*udict_nodealloc_t)(void *);
typedef void (*udict_nodefree_t)(void *, udict_node_t *);
typedef struct _RTL_AVL_TABLE udict_t;
typedef struct udict_operations {
void (*udict_init)(udict_t *);
void (*udict_insert)(udict_t *, udict_node_t *, const void *);
void (*udict_delete)(udict_t *, udict_node_t *);
udict_node_t *(*udict_lookup)(udict_t *, const void *);
udict_node_t *(*udict_lower_bound)(udict_t *, const void *);
udict_node_t *(*udict_upper_bound)(udict_t *, const void *);
udict_node_t *(*udict_first)(udict_t *);
udict_node_t *(*udict_last)(udict_t *);
udict_node_t *(*udict_next)(udict_t *, udict_node_t *);
udict_node_t *(*udict_prev)(udict_t *, udict_node_t *);
void (*udict_convert_to_list)(udict_t *);
void (*udict_convert_from_list)(udict_t *);
udict_algkind_t udict_kind;
} udict_operations_t;
/* non-virtual dict methods */
void udict_init(udict_t *, int, udict_count_t, udict_compare_t);
udict_t *udict_create(int, udict_count_t, udict_compare_t);
void udict_destroy(udict_t *);
void udict_convert_to(udict_t *, int);
udict_count_t udict_count(udict_t *);
int udict_isempty(udict_t *);
int udict_isfull(udict_t *);
int udict_alloc_insert(udict_t *, const void *, void *);
void udict_delete_free(udict_t *, udict_node_t *);
void udict_set_allocator(udict_t *, udict_nodealloc_t, udict_nodefree_t, void *);
void udict_allow_dupes(udict_t *);
/* non-virtual node methods */
void udict_node_init(udict_node_t *, void *);
udict_node_t *udict_node_create(void *);
void udict_node_destroy(udict_node_t *);
void *udict_node_getdata(udict_node_t *);
void udict_node_setdata(udict_node_t *, void *);
const void *udict_node_getkey(udict_node_t *);
/* virtual dict method wrappers */
void udict_insert(udict_t *, udict_node_t *, const void *);
void udict_delete(udict_t *, udict_node_t *);
udict_node_t *udict_lookup(udict_t *, const void *);
udict_node_t *udict_lower_bound(udict_t *, const void *);
udict_node_t *udict_upper_bound(udict_t *, const void *);
udict_node_t *udict_first(udict_t *);
udict_node_t *udict_last(udict_t *);
udict_node_t *udict_next(udict_t *, udict_node_t *);
udict_node_t *udict_prev(udict_t *, udict_node_t *);