VirtualBox

Changeset 4687

Show
Ignore:
Timestamp:
09/11/07 11:13:32 (1 year ago)
Author:
vboxsync
Message:

Added RTAvllU32*. Applied enumeration fixes for non-unique tree. Applied Destroy fixes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/iprt/avl.h

    r4071 r4687  
    146146RTDECL(int)             RTAvlU32DoWithAll(PPAVLU32NODECORE ppTree, int fFromLeft, PAVLU32CALLBACK pfnCallBack, void *pvParam); 
    147147RTDECL(int)             RTAvlU32Destroy(PPAVLU32NODECORE pTree, PAVLU32CALLBACK pfnCallBack, void *pvParam); 
     148 
     149/** @} */ 
     150 
     151 
     152 
     153/** AVL tree of uint32_t, list duplicates. 
     154 * @{ 
     155 */ 
     156 
     157/** AVL key type. */ 
     158typedef uint32_t    AVLLU32KEY; 
     159 
     160/** AVL Core node. */ 
     161typedef struct _AVLLU32NodeCore 
     162{ 
     163    AVLLU32KEY                  Key;        /**< Key value. */ 
     164    unsigned char               uchHeight;  /**< Height of this tree: max(height(left), height(right)) + 1 */ 
     165    struct _AVLLU32NodeCore    *pLeft;      /**< Pointer to left leaf node. */ 
     166    struct _AVLLU32NodeCore    *pRight;     /**< Pointer to right leaf node. */ 
     167    struct _AVLLU32NodeCore    *pList;      /**< Pointer to next node with the same key. */ 
     168} AVLLU32NODECORE, *PAVLLU32NODECORE, **PPAVLLU32NODECORE; 
     169 
     170/** Callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy(). */ 
     171typedef DECLCALLBACK(int) AVLLU32CALLBACK(PAVLLU32NODECORE, void*); 
     172/** Pointer to callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy(). */ 
     173typedef AVLLU32CALLBACK *PAVLLU32CALLBACK; 
     174 
     175 
     176/* 
     177 * Functions. 
     178 */ 
     179RTDECL(bool)                RTAvllU32Insert(PPAVLLU32NODECORE ppTree, PAVLLU32NODECORE pNode); 
     180RTDECL(PAVLLU32NODECORE)    RTAvllU32Remove(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key); 
     181RTDECL(PAVLLU32NODECORE)    RTAvllU32Get(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key); 
     182RTDECL(PAVLLU32NODECORE)    RTAvllU32GetBestFit(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key, bool fAbove); 
     183RTDECL(PAVLLU32NODECORE)    RTAvllU32RemoveBestFit(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key, bool fAbove); 
     184RTDECL(int)                 RTAvllU32DoWithAll(PPAVLLU32NODECORE ppTree, int fFromLeft, PAVLLU32CALLBACK pfnCallBack, void *pvParam); 
     185RTDECL(int)                 RTAvllU32Destroy(PPAVLLU32NODECORE pTree, PAVLLU32CALLBACK pfnCallBack, void *pvParam); 
    148186 
    149187/** @} */ 
  • trunk/src/VBox/Runtime/Makefile.kmk

    r4674 r4687  
    153153        table/avlroioport.cpp \ 
    154154        table/avlu32.cpp \ 
     155        table/avllu32.cpp \ 
    155156        table/avlul.cpp \ 
    156157        table/table.cpp \ 
  • trunk/src/VBox/Runtime/table/avl_Destroy.cpp.h

    r4071 r4687  
    55 
    66/* 
    7  * Copyright (C) 1999-2004 knut st. osmundsen (bird-src-spam@anduin.net) 
     7 * Copyright (C) 1999-2007 knut st. osmundsen (bird-src-spam@anduin.net) 
    88 * 
    99 * This file is part of VirtualBox Open Source Edition (OSE), as 
     
    2121 
    2222/** 
    23  * Iterates thru all nodes in the given tree so the caller can free resources 
    24  * associated with each node. 
     23 * Destroys the specified tree, starting with the root node and working our way down. 
    2524 * 
    26  * @returns     0 on success. 
    27  * @returns     Return code from the callback on failure. The tree might be half 
    28  *              destroyed at this point and will not behave correctly when any 
    29  *              insert or remove operation is attempted. 
    30  * 
    31  * @param       ppTree          Pointer to the AVL-tree root node pointer. 
    32  * @param       pfnCallBack     Pointer to callback function. 
    33  * @param       pvParam         User parameter passed on to the callback function. 
     25 * @returns 0 on success. 
     26 * @returns Return value from callback on failure. On failure, the tree will be in 
     27 *          an unbalanced condition and only further calls to the Destroy should be 
     28 *          made on it. Note that the node we fail on will be considered dead and 
     29 *          no action is taken to link it back into the tree. 
     30 * @param   ppTree          Pointer to the AVL-tree root node pointer. 
     31 * @param   pfnCallBack     Pointer to callback function. 
     32 * @param   pvUser          User parameter passed on to the callback function. 
    3433 */ 
    35 RTDECL(int) KAVL_FN(Destroy)(PPKAVLNODECORE ppTree, PKAVLCALLBACK pfnCallBack, void *pvParam
     34RTDECL(int) KAVL_FN(Destroy)(PPKAVLNODECORE ppTree, PKAVLCALLBACK pfnCallBack, void *pvUser
    3635{ 
    37     KAVLSTACK2      AVLStack; 
     36    unsigned        cEntries; 
     37    PKAVLNODECORE   apEntries[KAVL_MAX_STACK]; 
     38    int             rc; 
     39 
    3840    if (*ppTree == KAVL_NULL) 
    3941        return 0; 
    4042 
    41     AVLStack.cEntries = 1; 
    42     AVLStack.achFlags[0] = 0; 
    43     AVLStack.aEntries[0] = KAVL_GET_POINTER(ppTree); 
    44     while (AVLStack.cEntries > 0) 
     43    cEntries = 1; 
     44    apEntries[0] = KAVL_GET_POINTER(ppTree); 
     45    while (cEntries > 0) 
    4546    { 
    46         int             rc; 
    47         PKAVLNODECORE   pNode = AVLStack.aEntries[AVLStack.cEntries - 1]; 
     47        /* 
     48         * Process the subtrees first. 
     49         */ 
     50        PKAVLNODECORE pNode = apEntries[cEntries - 1]; 
     51        if (pNode->pLeft != KAVL_NULL) 
     52            apEntries[cEntries++] = KAVL_GET_POINTER(&pNode->pLeft); 
     53        else if (pNode->pRight != KAVL_NULL) 
     54            apEntries[cEntries++] = KAVL_GET_POINTER(&pNode->pRight); 
     55        else 
     56        { 
     57#ifdef KAVL_EQUAL_ALLOWED 
     58            /* 
     59             * Process nodes with the same key. 
     60             */ 
     61            while (pNode->pList != KAVL_NULL) 
     62            { 
     63                PKAVLNODECORE pEqual = KAVL_GET_POINTER(&pNode->pList); 
     64                KAVL_SET_POINTER(&pNode->pList, KAVL_GET_POINTER_NULL(&pEqual->pList)); 
     65                pEqual->pList = KAVL_NULL; 
    4866 
    49         if (!AVLStack.achFlags[AVLStack.cEntries - 1]++) 
    50         { 
    51             /* push left and recurse */ 
    52             if (pNode->pLeft != KAVL_NULL) 
     67                rc = pfnCallBack(pEqual, pvUser); 
     68                if (rc) 
     69                    return rc; 
     70            } 
     71#endif 
     72 
     73            /* 
     74             * Unlink the node. 
     75             */ 
     76            if (--cEntries > 0) 
    5377            { 
    54                 AVLStack.achFlags[AVLStack.cEntries] = 0; /* 0 first, 1 last */ 
    55                 AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->pLeft); 
    56                 continue; 
     78                PKAVLNODECORE pParent = apEntries[cEntries - 1]; 
     79                if (KAVL_GET_POINTER(&pParent->pLeft) == pNode) 
     80                    pParent->pLeft = KAVL_NULL; 
     81                else 
     82                    pParent->pRight = KAVL_NULL; 
    5783            } 
     84            else 
     85                *ppTree = KAVL_NULL; 
     86 
     87            kASSERT(pNode->pLeft == KAVL_NULL); 
     88            kASSERT(pNode->pRight == KAVL_NULL); 
     89            rc = pfnCallBack(pNode, pvUser); 
     90            if (rc) 
     91                return rc; 
    5892        } 
    59  
    60         /* pop pNode */ 
    61         AVLStack.cEntries--; 
    62  
    63         /* push right */ 
    64         if (pNode->pRight != KAVL_NULL) 
    65         { 
    66             AVLStack.achFlags[AVLStack.cEntries] = 0; 
    67             AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->pRight); 
    68         } 
    69  
    70         /* call destructor */ 
    71         pNode->pRight = pNode->pLeft = KAVL_NULL; 
    72         rc = pfnCallBack(pNode, pvParam); 
    73         if (rc) 
    74             return rc; 
    75  
    7693    } /* while */ 
    7794 
    78     *ppTree = KAVL_NULL; 
     95    kASSERT(*ppTree == KAVL_NULL); 
     96 
    7997    return 0; 
    8098} 
    81  
    8299 
    83100#endif 
  • trunk/src/VBox/Runtime/table/avl_DoWithAll.cpp.h

    r4071 r4687  
    55 
    66/* 
    7  * Copyright (C) 1999-2002 knut st. osmundsen (bird-src-spam@anduin.net) 
     7 * Copyright (C) 1999-2007 knut st. osmundsen (bird-src-spam@anduin.net) 
    88 * 
    99 * This file is part of VirtualBox Open Source Edition (OSE), as 
     
    2121 
    2222/** 
    23  * Iterates tru all nodes in the given tree. 
     23 * Iterates thru all nodes in the given tree. 
    2424 * @returns   0 on success. Return from callback on failure. 
    2525 * @param     ppTree   Pointer to the AVL-tree root node pointer. 
     
    3333    KAVLSTACK2      AVLStack; 
    3434    PKAVLNODECORE   pNode; 
     35#ifdef KAVL_EQUAL_ALLOWED 
     36    PKAVLNODECORE   pEqual; 
     37#endif 
    3538    int             rc; 
    3639 
     
    6366            if (rc) 
    6467                return rc; 
     68#ifdef KAVL_EQUAL_ALLOWED 
     69            if (pNode->pList != KAVL_NULL) 
     70                for (pEqual = KAVL_GET_POINTER(&pNode->pList); pEqual; pEqual = KAVL_GET_POINTER_NULL(&pEqual->pList)) 
     71                { 
     72                    rc = pfnCallBack(pEqual, pvParam); 
     73                    if (rc) 
     74                        return rc; 
     75                } 
     76#endif 
    6577 
    6678            /* right */ 
     
    7991            pNode = AVLStack.aEntries[AVLStack.cEntries - 1]; 
    8092 
    81  
    8293            /* right */ 
    8394            if (!AVLStack.achFlags[AVLStack.cEntries - 1]++) 
     
    95106            if (rc) 
    96107                return rc; 
     108#ifdef KAVL_EQUAL_ALLOWED 
     109            if (pNode->pList != KAVL_NULL) 
     110                for (pEqual = KAVL_GET_POINTER(&pNode->pList); pEqual; pEqual = KAVL_GET_POINTER_NULL(&pEqual->pList)) 
     111                { 
     112                    rc = pfnCallBack(pEqual, pvParam); 
     113                    if (rc) 
     114                        return rc; 
     115                } 
     116#endif 
    97117 
    98118            /* left */ 
  • trunk/src/VBox/Runtime/table/avl_RemoveBestFit.cpp.h

    r4071 r4687  
    4545    if (pNode != NULL) 
    4646    { 
    47         #ifdef KAVL_EQUAL_ALLOWED 
     47#ifdef KAVL_EQUAL_ALLOWED 
    4848        if (pNode->pList != KAVL_NULL) 
    4949        { 
    50             PKAVLANODECORE pRet = KAVL_GET_POINTER(&pNode->pList); 
     50            PKAVLNODECORE pRet = KAVL_GET_POINTER(&pNode->pList); 
    5151            KAVL_SET_POINTER_NULL(&pNode->pList, &pRet->pList); 
    5252            return pRet; 
    5353        } 
    54         #endif 
     54#endif 
    5555        pNode = KAVL_FN(Remove)(ppTree, pNode->Key); 
    5656    } 
  • trunk/src/VBox/Runtime/table/avllu32.cpp

    r4071 r4687  
    2626 * AVL configuration. 
    2727 */ 
    28 #define KAVL_FN(a)                  RTAvlU32##a 
     28#define KAVL_FN(a)                  RTAvllU32##a 
    2929#define KAVL_MAX_STACK              27  /* Up to 2^24 nodes. */ 
    30 #define KAVL_CHECK_FOR_EQUAL_INSERT 1   /* No duplicate keys! */ 
    31 #define KAVLNODECORE                AVLU32NODECORE 
    32 #define PKAVLNODECORE               PAVLU32NODECORE 
    33 #define PPKAVLNODECORE              PPAVLU32NODECORE 
    34 #define KAVLKEY                     AVLU32KEY 
    35 #define PKAVLKEY                    PAVLU32KEY 
    36 #define KAVLENUMDATA                AVLU32ENUMDATA 
    37 #define PKAVLENUMDATA               PAVLU32ENUMDATA 
    38 #define PKAVLCALLBACK               PAVLU32CALLBACK 
     30#define KAVL_EQUAL_ALLOWED          1   /* List duplicate keys! */ 
     31#define KAVLNODECORE                AVLLU32NODECORE 
     32#define PKAVLNODECORE               PAVLLU32NODECORE 
     33#define PPKAVLNODECORE              PPAVLLU32NODECORE 
     34#define KAVLKEY                     AVLLU32KEY 
     35#define PKAVLKEY                    PAVLLU32KEY 
     36#define KAVLENUMDATA                AVLLU32ENUMDATA 
     37#define PKAVLENUMDATA               PAVLLU32ENUMDATA 
     38#define PKAVLCALLBACK               PAVLLU32CALLBACK 
    3939 
    4040 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy