|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 16322 (0x3fc2)
Types: TextFile
Names: »avl.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦697af93db⟧ »EurOpenD3/network/snmp/mit-snmp.tar.Z«
└─⟦57bbcbe75⟧
└─⟦this⟧ »./snmp/avl.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦925ee6880⟧ »EurOpenD3/network/snmp/mit-snmp.900225.tar.Z«
└─⟦a4bfa469c⟧
└─⟦this⟧ »./snmp/avl.c«
/*
* $Header: avl.c,v 1.1 89/01/11 22:09:02 jrd Exp $
* Author: J. Davin
* Copyright 1988, 1989, Massachusetts Institute of Technology
* See permission and disclaimer notice in file "notice.h"
*/
#include <notice.h>
#include <ctypes.h>
#include <debug.h>
#include <local.h>
#include <avl.h>
#define avlDirOpposite(x) \
(((x) == avlDirLeft) ? avlDirRight : avlDirLeft)
typedef struct AvlTag {
AvlInfoType avlInfo;
AvlBalanceType avlBal;
AvlIdType avlRefs [ 3 ];
} AvlType;
typedef AvlType *AvlPtrType;
#define avlIdToPtr(x) ((AvlPtrType) ((AvlIdType) (x)))
#define avlPtrToId(x) ((AvlIdType) ((AvlPtrType) (x)))
#define avlLinkGet(p, c) ((avlIdToPtr (p))->avlRefs \
[ (int) (c) ])
#define avlLinkSet(p, c, q) (((avlIdToPtr (p))->avlRefs \
[ (int) (c) ]) = (q))
#define avlLeftGet(p) ((avlIdToPtr (p))->avlRefs \
[ (int) avlDirLeft ])
#define avlLeftSet(p, q) (((avlIdToPtr (p))->avlRefs \
[ (int) avlDirLeft ]) = (q))
#define avlRightGet(p) ((avlIdToPtr (p))->avlRefs \
[ (int) avlDirRight ])
#define avlRightSet(p, q) (((avlIdToPtr (p))->avlRefs \
[ (int) avlDirRight ]) = (q))
#define avlBalGet(p) ((avlIdToPtr (p))->avlBal)
#define avlBalSet(p, c) (((avlIdToPtr (p))->avlBal) = (c))
#define avlInfoGet(p) ((avlIdToPtr (p))->avlInfo)
#define avlInfoSet(p, w) (((avlIdToPtr (p))->avlInfo) = (w))
#define avlCmpFnGet(p) ((AvlCmpFnType) avlInfoGet ((p)))
#define avlCmpFnSet(p, f) (avlInfoSet ((p), (AvlInfoType) (f)))
#define avlPrintFnGet(p) ((AvlPrintFnType) \
avlLinkGet ((p), avlDirBalanced))
#define avlPrintFnSet(p, f) ((AvlPrintFnType) \
avlLinkSet ((p), \
avlDirBalanced, (AvlIdType) (f)))
typedef struct AvlStepTag {
AvlIdType avlStepNode;
AvlBalanceType avlStepDir;
} AvlStepType;
#define avlPathSize (512)
typedef CUnsfType AvlLevelType;
typedef struct AvlPathTag {
AvlLevelType avlPathLevel;
AvlStepType avlPathSteps [ 1 ];
} AvlPathType;
typedef AvlPathType *AvlPathPtrType;
typedef CUnswType AvlPathIdType;
#define avlPathIdToPtr(p) \
((AvlPathPtrType) ((AvlPathIdType) (p)))
#define avlPathPtrToId(p) \
((AvlPathIdType) ((AvlPathPtrType) (p)))
#define avlPathNew(cp, n) \
((((AvlPathPtrType) cp)->avlPathLevel = 0), \
(avlPathPtrToId (cp)))
#define avlPathDirGet(p, j) \
((avlPathIdToPtr (p))->avlPathSteps[ (j) ].avlStepDir)
#define avlPathDirSet(p, j, d) \
((avlPathIdToPtr (p))->avlPathSteps[ (j) ].avlStepDir \
= (d))
#define avlPathNodeGet(p, j) \
((avlPathIdToPtr (p))->avlPathSteps[ (j) ].avlStepNode)
#define avlPathNodeSet(p, j, d) \
((avlPathIdToPtr (p))->avlPathSteps[ (j) ].avlStepNode \
= (d))
#define avlPathLevelGet(p) \
((avlPathIdToPtr (p))->avlPathLevel)
#define avlPathLevelSet(p, d) \
((avlPathIdToPtr (p))->avlPathLevel = (d))
#ifdef DEBUG
static AvlStatusType avlPrintNode (p, printFn)
AvlIdType p;
AvlPrintFnType printFn;
{
printf ("(");
if (p != (AvlIdType) 0) {
(void) avlPrintNode (avlLeftGet (p), printFn);
printf ("[%d]", avlBalGet (p));
(*printFn) (avlInfoGet (p));
(void) avlPrintNode (avlRightGet (p), printFn);
}
printf (")");
return (errOk);
}
static AvlStatusType avlPrint (p)
AvlIdType p;
{
if (p != (AvlIdType) 0) {
if (avlPrintFnGet (p) != (AvlPrintFnType) 0) {
(void) avlPrintNode (avlRightGet (p),
avlPrintFnGet (p));
}
}
else {
printf ("NIL");
}
return (errOk);
}
static CIntfType avlVerifyNode (p)
AvlIdType p;
{
CIntfType l;
CIntfType r;
CIntfType d;
CIntfType result;
AvlBalanceType c;
AvlBalanceType e;
if (p == (AvlIdType) 0) {
return ((CIntfType) 0);
}
l = avlVerifyNode (avlLeftGet (p));
r = avlVerifyNode (avlRightGet (p));
c = avlBalGet (p);
if (l > r) {
result = l;
d = l - r;
e = avlDirLeft;
}
else if (l < r) {
result = r;
d = r - l;
e = avlDirRight;
}
else {
result = r;
d = 0;
e = avlDirBalanced;
}
result++;
if ((d > 1) || (c != e)) {
printf ("avlVerify: Node %08.08X bad\n", p);
}
return (result);
}
static CIntfType avlVerify (p)
AvlIdType p;
{
CIntfType r;
if (p != (AvlIdType) 0) {
r = avlVerifyNode (avlRightGet (p));
}
else {
r = (CIntfType) 0;
}
return (r);
}
static CVoidType avlPathPrint (path)
AvlPathIdType path;
{
AvlLevelType level;
AvlLevelType i;
if (path != (AvlPathIdType) 0) {
level = avlPathLevelGet (path);
printf ("avlPathPrint: level %d\n", level);
for (i = 1; i <= level; i++) {
printf ("%08.08.X %d\n", avlPathNodeGet (path, i),
avlPathDirGet (path, i));
}
}
}
#define DEBUGAVLPATH(p) avlPathPrint ((p))
#define DEBUGAVLVERIFY(p) (void) avlVerify ((p))
#define DEBUGAVLTREE(p) (void) avlPrint ((p))
#else /* DEBUG */
#define DEBUGAVLPATH(p)
#define DEBUGAVLVERIFY(p)
#define DEBUGAVLTREE(p)
#endif /* DEBUG */
CVoidType avlInit ()
{
DEBUGAVLPATH ((AvlPathIdType) 0);
DEBUGAVLVERIFY ((AvlIdType) 0);
DEBUGAVLTREE ((AvlIdType) 0);
}
static AvlIdType avlFreeNode (p)
AvlIdType p;
{
if (p != (AvlIdType) 0) {
(void) free ((char *) avlIdToPtr (p));
}
return ((AvlIdType) 0);
}
AvlIdType avlFree (p)
AvlIdType p;
{
if (p != (AvlIdType) 0) {
(void) avlFree (avlLeftGet (p));
(void) avlFree (avlRightGet (p));
}
return (avlFreeNode (p));
}
static AvlIdType avlAllocNode ()
{
AvlPtrType p;
p = (AvlPtrType) malloc ((unsigned) sizeof (*p));
if (p != (AvlPtrType) 0) {
(void) bzero ((char *) p, (int) sizeof (*p));
}
return (avlPtrToId (p));
}
AvlIdType avlNew (cmpFn, printFn)
AvlCmpFnType cmpFn;
AvlPrintFnType printFn;
{
AvlIdType p;
if ((p = avlAllocNode ()) != (AvlIdType) 0) {
(void) avlCmpFnSet (p, cmpFn);
(void) avlRightSet (p, (AvlIdType) 0);
(void) avlLeftSet (p, (AvlIdType) printFn);
(void) avlBalSet (p, avlDirBalanced);
}
return (p);
}
static AvlIdType avlChangeHead (root, j, path)
AvlIdType root;
AvlLevelType j;
AvlPathIdType path;
{
AvlLevelType level;
level = avlPathLevelGet (path);
if (level == 1) {
root = avlPathNodeGet (path, j);
}
else {
level--;
(void) avlLinkSet (avlPathNodeGet (path, level),
avlPathDirGet (path, level),
avlPathNodeGet (path, j));
}
return (root);
}
#ifdef INLINE
#define avlExchange(path, a, b) \
(void) avlLinkSet (avlPathNodeGet ((path), (a)), \
avlPathDirGet ((path), (a)), \
avlLinkGet (avlPathNodeGet ((path), (b)), \
avlDirOpposite (avlPathDirGet ((path), (a))))); \
(void) avlLinkSet (avlPathNodeGet ((path), (b)), \
avlDirOpposite (avlPathDirGet ((path), (a))), \
avlPathNodeGet ((path), (a)));
#else /* INLINE */
static CVoidType avlExchange (path, a, b)
AvlPathIdType path;
AvlLevelType a;
AvlLevelType b;
{
(void) avlLinkSet (avlPathNodeGet (path, a),
avlPathDirGet (path, a),
avlLinkGet (avlPathNodeGet (path, b),
avlDirOpposite (avlPathDirGet (path, a))));
(void) avlLinkSet (avlPathNodeGet (path, b),
avlDirOpposite (avlPathDirGet (path, a)),
avlPathNodeGet (path, a));
}
#endif /* INLINE */
#ifdef INLINE
#define avlSavePath(path, place, dir) \
{ \
AvlLevelType level; \
level = avlPathLevelGet ((path)) + 1; \
(void) avlPathLevelSet ((path), level); \
(void) avlPathNodeSet ((path), level, (place)); \
(void) avlPathDirSet ((path), level, (dir)); \
}
#else /* INLINE */
static CVoidType avlSavePath (path, place, dir)
AvlPathIdType path;
AvlIdType place;
AvlBalanceType dir;
{
AvlLevelType level;
level = avlPathLevelGet (path) + 1;
(void) avlPathLevelSet (path, level);
(void) avlPathNodeSet (path, level, place);
(void) avlPathDirSet (path, level, dir);
}
#endif /* INLINE */
static AvlIdType avlSearchNode (root, name, namelen, path, cmpFn)
AvlIdType root;
AvlNamePtrType name;
AvlLengthType namelen;
AvlPathIdType path;
AvlCmpFnType cmpFn;
{
AvlIdType where;
AvlBalanceType dir;
CBoolType notfound;
where = root;
notfound = TRUE;
while ((where != (AvlIdType) 0) && (notfound)) {
dir = (*cmpFn) (avlInfoGet (where), name, namelen);
if (dir == avlDirBalanced) {
notfound = FALSE;
}
else {
avlSavePath (path, where, dir);
where = avlLinkGet (where, dir);
}
}
return (where);
}
AvlInfoType avlFind (head, name, namelen)
AvlIdType head;
AvlNamePtrType name;
AvlLengthType namelen;
{
AvlIdType where;
AvlIdType root;
AvlPathIdType path;
CByteType pathArea [ avlPathSize ];
if (head == (AvlIdType) 0) {
return ((AvlInfoType) 0);
}
root = avlRightGet (head);
path = avlPathNew (pathArea, avlPathSize);
if (path == (AvlPathIdType) 0) {
return ((AvlInfoType) 0);
}
where = avlSearchNode (root, name, namelen, path, avlCmpFnGet (head));
if (where == (AvlIdType) 0) {
return ((AvlInfoType) 0);
}
return (avlInfoGet (where));
}
static AvlIdType avlCessorNode (p, path)
AvlIdType p;
AvlPathIdType path;
{
AvlLevelType level;
AvlIdType n;
if ((p == (AvlIdType) 0) || ((n = avlRightGet (p)) ==
(AvlIdType) 0)) {
for (level = avlPathLevelGet (path); ((level != 0) &&
(avlPathDirGet (path, level) == avlDirRight));
level--);
if (level == 0) {
(void) avlPathLevelSet (path, level);
return ((AvlIdType) 0);
}
else {
p = avlPathNodeGet (path, level);
(void) avlPathLevelSet (path, level - 1);
return (p);
}
}
else {
avlSavePath (path, p, avlDirRight);
p = n;
while ((n = avlLeftGet (p)) != (AvlIdType) 0) {
avlSavePath (path, p, avlDirLeft);
p = n;
}
return (p);
}
}
AvlInfoType avlCessor (head, name, namelen)
AvlIdType head;
AvlNamePtrType name;
AvlLengthType namelen;
{
AvlIdType where;
AvlPathIdType path;
CByteType pathArea [ avlPathSize ];
if (head == (AvlIdType) 0) {
return ((AvlInfoType) 0);
}
path = avlPathNew (pathArea, avlPathSize);
if (path == (AvlPathIdType) 0) {
return ((AvlInfoType) 0);
}
where = avlSearchNode (avlRightGet (head), name, namelen,
path, avlCmpFnGet (head));
where = avlCessorNode (where, path);
if (where == (AvlIdType) 0) {
return ((AvlInfoType) 0);
}
return (avlInfoGet (where));
}
static AvlIdType avlCriticalNode (root, path, level)
AvlIdType root;
AvlPathIdType path;
AvlLevelType level;
{
(void) avlPathLevelSet (path, level);
if (avlPathDirGet (path, level) ==
avlPathDirGet (path, level + 1)) {
root = avlChangeHead (root, level + 1, path);
avlExchange (path, level, level + 1);
(void) avlBalSet (avlPathNodeGet (path, level),
avlDirBalanced);
(void) avlBalSet (avlPathNodeGet (path, level + 1),
avlDirBalanced);
}
else {
root = avlChangeHead (root, level + 2, path);
avlExchange (path, level, level + 2);
avlExchange (path, level + 1, level + 2);
(void) avlBalSet (avlPathNodeGet (path, level + 2),
avlDirBalanced);
if (avlPathDirGet (path, level + 1) ==
avlPathDirGet (path, level + 2)) {
(void) avlBalSet (avlPathNodeGet (path, level),
avlDirBalanced);
(void) avlBalSet (avlPathNodeGet (path,
level + 1), avlDirOpposite (
avlPathDirGet (path, level + 1)));
}
else if (avlPathDirGet (path, level + 2) !=
avlDirBalanced) {
(void) avlBalSet (avlPathNodeGet (path,
level), avlDirOpposite (
avlPathDirGet (path, level)));
(void) avlBalSet (avlPathNodeGet (path,
level + 1), avlDirBalanced);
}
else {
(void) avlBalSet (avlPathNodeGet (path, level),
avlDirBalanced);
(void) avlBalSet (avlPathNodeGet (path,
level + 1), avlDirBalanced);
}
}
return (root);
}
AvlStatusType avlInsert (head, name, namelen, info)
AvlIdType head;
AvlNamePtrType name;
AvlLengthType namelen;
AvlInfoType info;
{
CBoolType notdone;
AvlIdType where;
AvlIdType root;
AvlBalanceType weight;
AvlPathIdType path;
CByteType pathArea [ avlPathSize ];
AvlLevelType level;
AvlBalanceType dir;
AvlIdType node;
if (head == (AvlIdType) 0) {
return (errBad);
}
if (info == (AvlInfoType) 0) {
return (errBad);
}
root = avlRightGet (head);
path = avlPathNew (pathArea, avlPathSize);
if (path == (AvlPathIdType) 0) {
return (errBad);
}
where = avlSearchNode (root, name, namelen, path, avlCmpFnGet (head));
if (where != (AvlIdType) 0) {
return (errBad);
}
where = avlAllocNode ();
if (where == (AvlIdType) 0) {
return (errBad);
}
(void) avlInfoSet (where, info);
(void) avlLeftSet (where, (AvlIdType) 0);
(void) avlRightSet (where, (AvlIdType) 0);
(void) avlBalSet (where, avlDirBalanced);
avlSavePath (path, where, avlDirBalanced);
level = avlPathLevelGet (path);
root = avlChangeHead (root, level, path);
notdone = TRUE;
for (level = level - 1; (level != 0) && (notdone); level--) {
node = avlPathNodeGet (path, level);
weight = avlBalGet (node);
dir = avlPathDirGet (path, level);
if (weight == dir) {
root = avlCriticalNode (root, path, level);
notdone = FALSE;
}
else {
(void) avlBalSet (node, dir);
if (weight != avlDirBalanced) {
(void) avlBalSet (node, avlDirBalanced);
notdone = FALSE;
}
}
}
(void) avlRightSet (head, root);
DEBUGAVLVERIFY (root);
DEBUGAVLTREE (root);
DEBUG0 ("\n");
return (errOk);
}
AvlStatusType avlRemove (head, name, namelen)
AvlIdType head;
AvlNamePtrType name;
AvlLengthType namelen;
{
CBoolType notdone;
AvlPathIdType path;
CByteType pathArea [ avlPathSize ];
AvlLevelType level;
AvlBalanceType dir;
AvlBalanceType opp;
AvlBalanceType bal;
AvlBalanceType balb;
AvlIdType root;
AvlIdType a;
AvlIdType b;
AvlIdType x;
AvlIdType p;
AvlIdType q;
AvlIdType n;
if (head == (AvlIdType) 0) {
return (errBad);
}
path = avlPathNew (pathArea, avlPathSize);
if (path == (AvlPathIdType) 0) {
return (errBad);
}
root = avlRightGet (head);
avlSavePath (path, head, avlDirRight);
p = avlSearchNode (root, name, namelen, path, avlCmpFnGet (head));
if (p == (AvlIdType) 0) {
return (errBad);
}
q = p;
avlSavePath (path, p, avlDirRight);
if (avlRightGet (p) != (AvlIdType) 0) {
q = avlRightGet (p);
avlSavePath (path, q, avlDirLeft);
while ((n = avlLeftGet (q)) != (AvlIdType) 0) {
q = n;
avlSavePath (path, q, avlDirLeft);
}
}
(void) avlInfoSet (p, avlInfoGet (q));
level = avlPathLevelGet (path);
(void) avlLinkSet (
avlPathNodeGet (path, level - 1),
avlPathDirGet (path, level - 1),
avlLinkGet (
avlPathNodeGet (path, level),
avlDirOpposite (avlPathDirGet (path, level))));
(void) avlFreeNode (q);
notdone = TRUE;
for (level = level - 1; (level > 1) && (notdone); level--) {
a = avlPathNodeGet (path, level);
bal = avlBalGet (a);
dir = avlPathDirGet (path, level);
opp = avlDirOpposite (dir);
b = avlLinkGet (a, opp);
balb = avlBalGet (b);
if (bal == dir) {
(void) avlBalSet (a, avlDirBalanced);
}
else if (bal == avlDirBalanced) {
(void) avlBalSet (a, opp);
notdone = FALSE;
}
else if (balb == avlDirBalanced) {
/* Rebalance: case 3 */
(void) avlLinkSet (a, opp, avlLinkGet (b, dir));
(void) avlLinkSet (b, dir, a);
(void) avlBalSet (a, opp);
(void) avlBalSet (b, dir);
(void) avlLinkSet (avlPathNodeGet (path,
level - 1), avlPathDirGet (path,
level - 1), b);
notdone = FALSE;
}
else if (balb == opp) {
/* Rebalance: case 1 */
(void) avlLinkSet (a, opp, avlLinkGet (b, dir));
(void) avlLinkSet (b, dir, a);
(void) avlBalSet (a, avlDirBalanced);
(void) avlBalSet (b, avlDirBalanced);
(void) avlLinkSet (avlPathNodeGet (path,
level - 1), avlPathDirGet (path,
level - 1), b);
}
else {
/* Rebalance: case 2 */
x = avlLinkGet (b, balb);
(void) avlLinkSet (a, opp, avlLinkGet (x, dir));
(void) avlLinkSet (b, dir, avlLinkGet (x, opp));
(void) avlLinkSet (x, opp, b);
(void) avlLinkSet (x, dir, a);
if (avlBalGet (x) == avlDirBalanced) {
(void) avlBalSet (a, avlDirBalanced);
(void) avlBalSet (b, avlDirBalanced);
}
else if (avlBalGet (x) == opp) {
(void) avlBalSet (a, dir);
(void) avlBalSet (b, avlDirBalanced);
(void) avlBalSet (x, avlDirBalanced);
}
else {
(void) avlBalSet (b, opp);
(void) avlBalSet (a, avlDirBalanced);
(void) avlBalSet (x, avlDirBalanced);
}
(void) avlLinkSet (avlPathNodeGet (path,
level - 1), avlPathDirGet (path,
level - 1), x);
}
}
root = avlRightGet (head);
DEBUGAVLVERIFY (root);
DEBUGAVLTREE (root);
DEBUG0 ("\n");
return (errOk);
}