]> git.sur5r.net Git - openldap/blobdiff - libraries/liblutil/avl.c
Merge remote branch 'origin/mdb.master'
[openldap] / libraries / liblutil / avl.c
index e5a5153d08fc11ceee4b295075891c73f1b2b701..497fbbdd8d04dbcaa71358a556f9fed38313c845 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2011 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
 
 #include "portable.h"
 
+#include <limits.h>
 #include <stdio.h>
 #include <ac/stdlib.h>
 
@@ -48,6 +49,9 @@
 #define AVL_INTERNAL
 #include "avl.h"
 
+/* Maximum tree depth this host's address space could support */
+#define MAX_TREE_DEPTH (sizeof(void *) * CHAR_BIT)
+
 static const int avl_bfs[] = {LH, RH};
 
 /*
@@ -180,8 +184,8 @@ avl_delete( Avlnode **root, void* data, AVL_CMP fcmp )
        int side, side_bf, shorter, nside;
 
        /* parent stack */
-       Avlnode *pptr[sizeof(void *)*8];
-       unsigned char pdir[sizeof(void *)*8];
+       Avlnode *pptr[MAX_TREE_DEPTH];
+       unsigned char pdir[MAX_TREE_DEPTH];
        int depth = 0;
 
        if ( *root == NULL )
@@ -230,14 +234,13 @@ avl_delete( Avlnode **root, void* data, AVL_CMP fcmp )
                /* fix stack positions: old parent of p points to q */
                pptr[side] = q;
                if ( side ) {
-                       --side;
-                       r = pptr[side];
-                       r->avl_link[pdir[side]] = q;
+                       r = pptr[side-1];
+                       r->avl_link[pdir[side-1]] = q;
                } else {
                        *root = q;
                }
                /* new parent of p points to p */
-               if ( depth > 1 ) {
+               if ( depth-side > 1 ) {
                        r = pptr[depth-1];
                        r->avl_link[1] = p;
                } else {
@@ -246,7 +249,7 @@ avl_delete( Avlnode **root, void* data, AVL_CMP fcmp )
        }
 
        /* now <p> has at most one child, get it */
-       q = p->avl_link[0];
+       q = p->avl_link[0] ? p->avl_link[0] : p->avl_link[1];
 
        ber_memfree( p );