VirtualBox

Changeset 7 in kStuff


Ignore:
Timestamp:
Feb 4, 2008 2:08:02 AM (17 years ago)
Author:
bird
Message:

kAVL: Implemented locking, root node and a direct cache.

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/k/kAvlTmpl/kAvlBase.h

    r2 r7  
    4848 *
    4949 *  \#define KAVL_MAX_STACK
    50  *  Use this to specify the max number of stack entries the stack will use when inserting
    51  *  and removing nodes from the tree. The size should be something like
     50 *  Use this to specify the max number of stack entries the stack will use when
     51 *  inserting and removing nodes from the tree. The size should be something like
    5252 *      log2(<max nodes>) + 3
    5353 *  Must be defined.
     
    6262 *  the exact same distance.
    6363 *
     64 *  \#define KAVL_LOOKTHRU
     65 *  Define this to employ a lookthru cache (direct) to speed up lookup for
     66 *  some usage patterns. The value should be the number of members of the
     67 *   array.
     68 *
     69 *  \#define KAVL_LOOKTHRU_HASH(Key)
     70 *  Define this to specify a more efficient translation of the key into
     71 *  a lookthru array index. The default is key % size.
     72 *  For some key types this is required as the default will not compile.
     73 *
     74 *  \#define KAVL_LOCKED
     75 *  Define this if you wish for the tree to be locked via the
     76 *  KAVL_WRITE_LOCK,  KAVL_WRITE_UNLOCK, KAVL_READ_LOCK and
     77 *  KAVL_READ_UNLOCK macros. If not defined the tree will not be subject
     78 *  do any kind of locking and the problem of concurrency is left the user.
     79 *
     80 *  \#define KAVL_WRITE_LOCK(pRoot)
     81 *  Lock the tree for writing.
     82 *
     83 *  \#define KAVL_WRITE_UNLOCK(pRoot)
     84 *  Counteracts KAVL_WRITE_LOCK.
     85 *
     86 *  \#define KAVL_READ_LOCK(pRoot)
     87 *  Lock the tree for reading.
     88 *
     89 *  \#define KAVL_READ_UNLOCK(pRoot)
     90 *  Counteracts KAVL_READ_LOCK.
     91 *
    6492 *  \#define KAVLKEY
    6593 *  Define this to the name of the AVL key type.
     
    6896 *  Define this to use the standard key compare macros. If not set all the
    6997 *  compare operations for KAVLKEY have to be defined: KAVL_G, KAVL_E, KAVL_NE,
    70  *  KAVL_R_IS_IDENTICAL, KAVL_R_IS_INTERSECTING and KAVL_R_IS_IN_RANGE. The latter
    71  *  three are only required when KAVL_RANGE is defined.
     98 *  KAVL_R_IS_IDENTICAL, KAVL_R_IS_INTERSECTING and KAVL_R_IS_IN_RANGE. The
     99 *  latter three are only required when KAVL_RANGE is defined.
    72100 *
    73101 *  \#define KAVLNODE
     
    83111 *  to KAVLNODE *.
    84112 *
     113 *  \#define KAVLROOT
     114 *  Define this to the name (typedef) of the AVL root structure. This
     115 *  is optional. However, if specified it must at least have a mpRoot
     116 *  member of KAVLTREEPTR type. If KAVL_LOOKTHRU is non-zero a
     117 *  maLookthru[KAVL_LOOKTHRU] member of the KAVLTREEPTR type is also
     118 *  required.
     119 *
    85120 *  \#define KAVL_FN
    86121 *  Use this to alter the names of the AVL functions.
     
    160195#ifndef KAVLTREEPTR
    161196# define KAVLTREEPTR                        KAVLNODE *
     197#endif
     198
     199#ifndef KAVLROOT
     200# define KAVLROOT                           KAVL_TYPE(,ROOT)
     201# define KAVL_NEED_KAVLROOT
     202#endif
     203
     204#ifdef KAVL_LOOKTHRU
     205# ifndef KAVL_LOOKTHRU_HASH
     206#  define KAVL_LOOKTHRU_HASH(Key)           ( (Key) % (KAVL_LOOKTHRU) )
     207# endif
     208#elif defined(KAVL_LOOKTHRU_HASH)
     209# error "KAVL_LOOKTHRU_HASH without KAVL_LOOKTHRU!"
     210#endif
     211
     212#ifdef KAVL_LOOKTHRU
     213# define KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, Key) \
     214    do { \
     215        KAVLTREEPTR **ppEntry = &pRoot->maLookthru[KAVL_LOOKTHRU_HASH(Key)]; \
     216        if ((pNode) == KAVL_GET_POINTER_NULL(ppEntry)) \
     217            *ppEntry = KAVL_NULL; \
     218    } while (0)
     219#else
     220# define KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, Key) do { } while (0)
     221#endif
     222
     223#ifndef KAVL_LOCKED
     224# define KAVL_WRITE_LOCK(pRoot)             do { } while (0)
     225# define KAVL_WRITE_UNLOCK(pRoot)           do { } while (0)
     226# define KAVL_READ_LOCK(pRoot)              do { } while (0)
     227# define KAVL_READ_UNLOCK(pRoot)            do { } while (0)
    162228#endif
    163229
     
    219285typedef int (* KAVL_TYPE(PFN,CALLBACK))(KAVLNODE *, void *);
    220286
     287#ifdef KAVL_NEED_KAVLROOT
     288/**
     289 * The AVL root structure.
     290 */
     291typedef struct
     292{
     293    KAVLTREEPTR     mpRoot;
     294# ifdef KAVL_LOOKTHRU
     295    KAVLTREEPTR     maLookthru[KAVL_LOOKTHRU];
     296# endif
     297} KAVLROOT;
     298#endif
    221299
    222300
     
    343421
    344422/**
     423 * Initializes the root of the AVL-tree.
     424 *
     425 * @param     pTree     Pointer to the root structure.
     426 */
     427KAVL_DECL(void) KAVL_FN(Init)(KAVLROOT *pRoot)
     428{
     429#ifdef KAVL_LOOKTHRU
     430    unsigned i;
     431#endif
     432
     433    pRoot->mpRoot = KAVL_NULL;
     434#ifdef KAVL_LOOKTHRU
     435    for (i = 0; i < (KAVL_LOOKTHRU); i++)
     436        pRoot->maLookthru[i] = KAVL_NULL;
     437#endif
     438}
     439
     440
     441/**
    345442 * Inserts a node into the AVL-tree.
    346  * @returns   TRUE if inserted.
    347  *            FALSE if node exists in tree.
    348  * @param     ppTree  Pointer to the AVL-tree root node pointer.
    349  * @param     pNode   Pointer to the node which is to be added.
     443 * @returns   K_TRUE if inserted.
     444 *            K_FALSE if node exists in tree.
     445 * @param     pRoot     Pointer to the AVL-tree root structure.
     446 * @param     pNode     Pointer to the node which is to be added.
    350447 * @sketch    Find the location of the node (using binary tree algorithm.):
    351448 *            LOOP until NULL leaf pointer
     
    360457 *            Rebalance the tree.
    361458 */
    362 KAVL_DECL(KBOOL) KAVL_FN(Insert)(KAVLTREEPTR *ppTree, KAVLNODE *pNode)
     459KAVL_DECL(KBOOL) KAVL_FN(Insert)(KAVLROOT *pRoot, KAVLNODE *pNode)
    363460{
    364461    KAVL_INT(STACK)     AVLStack;
    365     KAVLTREEPTR        *ppCurNode = ppTree;
     462    KAVLTREEPTR        *ppCurNode = &pRoot->mpRoot;
    366463    register KAVLKEY    Key = pNode->mKey;
    367464#ifdef KAVL_RANGE
     
    373470        return false;
    374471#endif
     472
     473    KAVL_WRITE_LOCK(pRoot);
    375474
    376475    AVLStack.cEntries = 0;
     
    391490            KAVL_SET_POINTER_NULL(&pNode->mpList, &pCurNode->mpList);
    392491            KAVL_SET_POINTER(&pCurNode->mpList, pNode);
     492            KAVL_WRITE_UNLOCK(pRoot);
    393493            return K_TRUE;
    394494        }
     
    396496#ifdef KAVL_CHECK_FOR_EQUAL_INSERT
    397497        if (KAVL_R_IS_INTERSECTING(pCurNode->mKey, Key, pCurNode->mKeyLast, KeyLast))
     498        {
     499            KAVL_WRITE_UNLOCK(pRoot);
    398500            return K_FALSE;
     501        }
    399502#endif
    400503        if (KAVL_G(pCurNode->mKey, Key))
     
    412515
    413516    KAVL_FN(Rebalance)(&AVLStack);
     517
     518    KAVL_WRITE_UNLOCK(pRoot);
    414519    return K_TRUE;
    415520}
     
    419524 * Removes a node from the AVL-tree.
    420525 * @returns   Pointer to the node.
    421  * @param     ppTree  Pointer to the AVL-tree root node pointer.
    422  * @param     Key     Key value of the node which is to be removed.
     526 * @param     pRoot     Pointer to the AVL-tree root structure.
     527 * @param     Key       Key value of the node which is to be removed.
    423528 * @sketch    Find the node which is to be removed:
    424529 *            LOOP until not found
     
    455560 *            return pointer to the removed node (if found).
    456561 */
    457 KAVL_DECL(KAVLNODE *) KAVL_FN(Remove)(KAVLTREEPTR *ppTree, KAVLKEY Key)
     562KAVL_DECL(KAVLNODE *) KAVL_FN(Remove)(KAVLROOT *pRoot, KAVLKEY Key)
    458563{
    459564    KAVL_INT(STACK)     AVLStack;
    460     KAVLTREEPTR        *ppDeleteNode = ppTree;
     565    KAVLTREEPTR        *ppDeleteNode = &pRoot->mpRoot;
    461566    register KAVLNODE  *pDeleteNode;
     567
     568    KAVL_WRITE_LOCK(pRoot);
    462569
    463570    AVLStack.cEntries = 0;
     
    465572    {
    466573        if (*ppDeleteNode == KAVL_NULL)
     574        {
     575            KAVL_WRITE_UNLOCK(pRoot);
    467576            return NULL;
     577        }
    468578        pDeleteNode = KAVL_GET_POINTER(ppDeleteNode);
    469579
     
    511621
    512622    KAVL_FN(Rebalance)(&AVLStack);
     623
     624    KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pDeleteNode, Key);
     625
     626    KAVL_WRITE_UNLOCK(pRoot);
    513627    return pDeleteNode;
    514628}
  • trunk/include/k/kAvlTmpl/kAvlDestroy.h

    r2 r7  
    4141 *          made on it. Note that the node we fail on will be considered dead and
    4242 *          no action is taken to link it back into the tree.
    43  * @param   ppTree          Pointer to the AVL-tree root node pointer.
     43 * @param   pRoot           Pointer to the AVL-tree root structure.
    4444 * @param   pfnCallBack     Pointer to callback function.
    4545 * @param   pvUser          User parameter passed on to the callback function.
    4646 */
    47 KAVL_DECL(int) KAVL_FN(Destroy)(KAVLTREEPTR *ppTree, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
     47KAVL_DECL(int) KAVL_FN(Destroy)(KAVLROOT *pRoot, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
    4848{
     49#ifdef KAVL_LOOKTHRU
     50    unsigned    i;
     51#endif
    4952    unsigned    cEntries;
    5053    KAVLNODE   *apEntries[KAVL_MAX_STACK];
    5154    int         rc;
    5255
    53     if (*ppTree == KAVL_NULL)
     56    KAVL_WRITE_LOCK(pRoot);
     57    if (pRoot->mpRoot == KAVL_NULL)
     58    {
     59        KAVL_WRITE_UNLOCK(pRoot);
    5460        return 0;
     61    }
     62
     63#ifdef KAVL_LOOKTHRU
     64    /*
     65     * Kill the lookthru cache.
     66     */
     67    for (i = 0; i < (KAVL_LOOKTHRU); i++)
     68        pRoot->maLookthru[i] = KAVL_NULL;
     69#endif
    5570
    5671    cEntries = 1;
    57     apEntries[0] = KAVL_GET_POINTER(ppTree);
     72    apEntries[0] = KAVL_GET_POINTER(&pRoot->mpRoot);
    5873    while (cEntries > 0)
    5974    {
     
    8095                rc = pfnCallBack(pEqual, pvUser);
    8196                if (rc)
     97                {
     98                    KAVL_WRITE_UNLOCK(pRoot);
    8299                    return rc;
     100                }
    83101            }
    84102#endif
     
    96114            }
    97115            else
    98                 *ppTree = KAVL_NULL;
     116                pRoot->mpRoot = KAVL_NULL;
    99117
    100118            kHlpAssert(pNode->mpLeft == KAVL_NULL);
     
    102120            rc = pfnCallBack(pNode, pvUser);
    103121            if (rc)
     122            {
     123                KAVL_WRITE_UNLOCK(pRoot);
    104124                return rc;
     125            }
    105126        }
    106127    } /* while */
    107     kHlpAssert(*ppTree == KAVL_NULL);
     128    kHlpAssert(pRoot->mpRoot == KAVL_NULL);
    108129
     130    KAVL_WRITE_UNLOCK(pRoot);
    109131    return 0;
    110132}
  • trunk/include/k/kAvlTmpl/kAvlDoWithAll.h

    r2 r7  
    4343    KAVLNODE       *aEntries[KAVL_MAX_STACK];
    4444    char            achFlags[KAVL_MAX_STACK];
     45    KAVLROOT        pRoot;
    4546} KAVL_INT(STACK2);
    4647
     
    5051 *
    5152 * @returns   0 on success. Return from callback on failure.
    52  * @param     ppTree       Pointer to the AVL-tree root node pointer.
     53 * @param     pRoot        Pointer to the AVL-tree root structure.
    5354 * @param     fFromLeft    K_TRUE:  Left to right.
    5455 *                         K_FALSE: Right to left.
     
    5657 * @param     pvUser       User parameter passed on to the callback function.
    5758 */
    58 KAVL_DECL(int) KAVL_FN(DoWithAll)(KAVLTREEPTR *ppTree, KBOOL fFromLeft, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
     59KAVL_DECL(int) KAVL_FN(DoWithAll)(KAVLROOT *pRoot, KBOOL fFromLeft, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)
    5960{
    6061    KAVL_INT(STACK2)    AVLStack;
     
    6566    int                 rc;
    6667
    67     if (*ppTree == KAVL_NULL)
     68    KAVL_READ_LOCK(pRoot);
     69    if (pRoot->mpRoot == KAVL_NULL)
     70    {
     71        KAVL_READ_UNLOCK(pRoot);
    6872        return 0;
     73    }
    6974
    7075    AVLStack.cEntries = 1;
    7176    AVLStack.achFlags[0] = 0;
    72     AVLStack.aEntries[0] = KAVL_GET_POINTER(ppTree);
     77    AVLStack.aEntries[0] = KAVL_GET_POINTER(&pRoot->mpRoot);
    7378
    7479    if (fFromLeft)
     
    99104                    rc = pfnCallBack(pEqual, pvUser);
    100105                    if (rc)
     106                    {
     107                        KAVL_READ_UNLOCK(pRoot);
    101108                        return rc;
     109                    }
    102110                }
    103111#endif
     
    139147                    rc = pfnCallBack(pEqual, pvUser);
    140148                    if (rc)
     149                    {
     150                        KAVL_READ_UNLOCK(pRoot);
    141151                        return rc;
     152                    }
    142153                }
    143154#endif
     
    153164    }
    154165
     166    KAVL_READ_UNLOCK(pRoot);
    155167    return 0;
    156168}
  • trunk/include/k/kAvlTmpl/kAvlEnum.h

    r2 r7  
    5151
    5252/**
     53 * Ends an enumeration.
     54 *
     55 * The purpose of this function is to unlock the tree should the
     56 * AVL implementation include locking. It's good practice to call
     57 * it anyway even if the tree doesn't do any locking.
     58 *
     59 * @param   pEnumData   Pointer to enumeration control data.
     60 */
     61KAVL_DECL(void) KAVL_FN(EndEnum)(KAVL_TYPE(,ENUMDATA) *pEnumData)
     62{
     63    KAVLROOT pRoot = pEnumData->pRoot;
     64    pEnumData->pRoot = NULL;
     65    if (pRoot)
     66        KAVL_READ_UNLOCK(pEnumData->pRoot);
     67}
     68
     69
     70/**
    5371 * Get the next node in the tree enumeration.
    5472 *
     
    5674 * chain like the DoWithAll function does. This may be changed later.
    5775 *
    58  * @returns Pointer to the first node in the tree.
     76 * @returns Pointer to the next node in the tree.
     77 *          NULL is returned when the end of the tree has been reached,
     78 *          it is not necessary to call EndEnum in this case.
    5979 * @param   pEnumData   Pointer to enumeration control data.
    6080 */
     
    130150    }
    131151
     152    /*
     153     * Call EndEnum.
     154     */
     155    KAVL_FN(EndEnum)(pEnumData);
    132156    return NULL;
    133157}
     
    137161 * Starts an enumeration of all nodes in the given AVL tree.
    138162 *
    139  * The current implementation of this function willl not walk the mpList
     163 * The current implementation of this function will not walk the mpList
    140164 * chain like the DoWithAll function does. This may be changed later.
    141165 *
    142166 * @returns Pointer to the first node in the enumeration.
    143  * @param   ppTree      Pointer to the AVL-tree root node pointer.
    144  * @param   pEnumData   Pointer to enumeration control data.
    145  * @param   fFromLeft   K_TRUE:  Left to right.
    146  *                      K_FALSE: Right to left.
     167 *          If NULL is returned the tree is empty calling EndEnum isn't
     168 *          strictly necessary (although it will do no harm).
     169 * @param   pRoot           Pointer to the AVL-tree root structure.
     170 * @param   pEnumData       Pointer to enumeration control data.
     171 * @param   fFromLeft       K_TRUE:  Left to right.
     172 *                          K_FALSE: Right to left.
    147173 */
    148 KAVL_DECL(KAVLNODE *) KAVL_FN(BeginEnum)(KAVLTREEPTR *ppTree, KAVL_TYPE(,ENUMDATA) *pEnumData, KBOOL fFromLeft)
     174KAVL_DECL(KAVLNODE *) KAVL_FN(BeginEnum)(KAVLROOT *pRoot, KAVL_TYPE(,ENUMDATA) *pEnumData, KBOOL fFromLeft)
    149175{
    150     if (*ppTree != KAVL_NULL)
     176    KAVL_READ_LOCK(pRoot);
     177    pEnumData->pRoot = pRoot;
     178    if (pRoot->mpRoot != KAVL_NULL)
    151179    {
    152180        pEnumData->fFromLeft = fFromLeft;
    153181        pEnumData->cEntries = 1;
    154         pEnumData->aEntries[0] = KAVL_GET_POINTER(ppTree);
     182        pEnumData->aEntries[0] = KAVL_GET_POINTER(pRoot->mpRoot);
    155183        pEnumData->achFlags[0] = 0;
    156184    }
  • trunk/include/k/kAvlTmpl/kAvlGet.h

    r2 r7  
    3636 * Gets a node from the tree (does not remove it!)
    3737 *
    38  * @returns   Pointer to the node holding the given key.
    39  * @param     ppTree  Pointer to the AVL-tree root node pointer.
    40  * @param     Key     Key value of the node which is to be found.
     38 * @returns Pointer to the node holding the given key.
     39 * @param   pRoot       Pointer to the AVL-tree root structure.
     40 * @param   Key         Key value of the node which is to be found.
    4141 */
    42 KAVL_DECL(KAVLNODE *) KAVL_FN(Get)(KAVLTREEPTR *ppTree, KAVLKEY Key)
     42KAVL_DECL(KAVLNODE *) KAVL_FN(Get)(KAVLROOT *pRoot, KAVLKEY Key)
    4343{
    4444    KAVLNODE *pNode;
    45     if (*ppTree == KAVL_NULL)
     45#ifdef KAVL_LOOKTHRU_CACHE
     46    KAVLTREEPTR *ppEntry;
     47#endif
     48
     49    KAVL_READ_LOCK(pRoot);
     50    if (pRoot->mpRoot == KAVL_NULL)
     51    {
     52        KAVL_READ_UNLOCK(pRoot);
    4653        return NULL;
     54    }
    4755
    48     pNode = KAVL_GET_POINTER(ppTree);
    49     while (KAVL_NE(pNode->mKey, Key))
     56#ifdef KAVL_LOOKTHRU_CACHE
     57    ppEntry = &pRoot->maLookthru[KAVL_LOOKTHRU_HASH(Key)];
     58    pNode = KAVL_GET_POINTER_NULL(ppEntry);
     59    if (!pNode || KAVL_NE(pNode->mKey, Key))
     60#endif
    5061    {
    51         if (KAVL_G(pNode->mKey, Key))
     62        pNode = KAVL_GET_POINTER(&pRoot->mpRoot);
     63        while (KAVL_NE(pNode->mKey, Key))
    5264        {
    53             if (pNode->mpLeft == KAVL_NULL)
    54                 return NULL;
    55             pNode = KAVL_GET_POINTER(&pNode->mpLeft);
     65            if (KAVL_G(pNode->mKey, Key))
     66            {
     67                if (pNode->mpLeft == KAVL_NULL)
     68                {
     69                    KAVL_READ_UNLOCK(pRoot);
     70                    return NULL;
     71                }
     72                pNode = KAVL_GET_POINTER(&pNode->mpLeft);
     73            }
     74            else
     75            {
     76                if (pNode->mpRight == KAVL_NULL)
     77                {
     78                    KAVL_READ_UNLOCK(pRoot);
     79                    return NULL;
     80                }
     81                pNode = KAVL_GET_POINTER(&pNode->mpRight);
     82            }
    5683        }
    57         else
    58         {
    59             if (pNode->mpRight == KAVL_NULL)
    60                 return NULL;
    61             pNode = KAVL_GET_POINTER(&pNode->mpRight);
    62         }
     84   
     85#ifdef KAVL_LOOKTHRU_CACHE
     86        KAVL_SET_POINTER(ppEntry, pNode);
     87#endif
    6388    }
     89
     90    KAVL_READ_UNLOCK(pRoot);
    6491    return pNode;
    6592}
  • trunk/include/k/kAvlTmpl/kAvlGetBestFit.h

    r2 r7  
    3737 *
    3838 * @returns Pointer to the best fitting node found.
    39  * @param   ppTree      Pointer to Pointer to the tree root node.
    40  * @param   Key         The Key of which is to be found a best fitting match for..
    41  * @param   fAbove      K_TRUE:  Returned node is have the closest key to Key from above.
    42  *                      K_FALSE: Returned node is have the closest key to Key from below.
     39 * @param   pRoot           Pointer to the AVL-tree root structure.
     40 * @param   Key             The Key of which is to be found a best fitting match for..
     41 * @param   fAbove          K_TRUE:  Returned node is have the closest key to Key from above.
     42 *                          K_FALSE: Returned node is have the closest key to Key from below.
    4343 * @sketch  The best fitting node is always located in the searchpath above you.
    4444 *          >= (above): The node where you last turned left.
    4545 *          <= (below): the node where you last turned right.
    4646 */
    47 KAVL_DECL(KAVLNODE *) KAVL_FN(GetBestFit)(KAVLTREEPTR *ppTree, KAVLKEY Key, KBOOL fAbove)
     47KAVL_DECL(KAVLNODE *) KAVL_FN(GetBestFit)(KAVLROOT *pRoot, KAVLKEY Key, KBOOL fAbove)
    4848{
    4949    register KAVLNODE  *pNode;
    5050    KAVLNODE           *pNodeLast;
    5151
    52     if (*ppTree == KAVL_NULL)
     52    KAVL_READ_LOCK(pLook);
     53    if (pRoot->mpRoot == KAVL_NULL)
     54    {
     55        KAVL_READ_UNLOCK(pLook);
    5356        return NULL;
     57    }
    5458
    55     pNode = KAVL_GET_POINTER(ppTree);
     59    pNode = KAVL_GET_POINTER(&pRoot->mpRoot);
    5660    pNodeLast = NULL;
    5761    if (fAbove)
     
    6266            {
    6367                if (pNode->mpLeft == KAVL_NULL)
     68                {
     69                    KAVL_READ_UNLOCK(pLook);
    6470                    return pNode;
     71                }
    6572                pNodeLast = pNode;
    6673                pNode = KAVL_GET_POINTER(&pNode->mpLeft);
     
    6976            {
    7077                if (pNode->mpRight == KAVL_NULL)
     78                {
     79                    KAVL_READ_UNLOCK(pLook);
    7180                    return pNodeLast;
     81                }
    7282                pNode = KAVL_GET_POINTER(&pNode->mpRight);
    7383            }
     
    8191            {
    8292                if (pNode->mpLeft == KAVL_NULL)
     93                {
     94                    KAVL_READ_UNLOCK(pLook);
    8395                    return pNodeLast;
     96                }
    8497                pNode = KAVL_GET_POINTER(&pNode->mpLeft);
    8598            }
     
    87100            {
    88101                if (pNode->mpRight == KAVL_NULL)
     102                {
     103                    KAVL_READ_UNLOCK(pLook);
    89104                    return pNode;
     105                }
    90106                pNodeLast = pNode;
    91107                pNode = KAVL_GET_POINTER(&pNode->mpRight);
     
    95111
    96112    /* perfect match or nothing. */
     113    KAVL_READ_UNLOCK(pLook);
    97114    return pNode;
    98115}
  • trunk/include/k/kAvlTmpl/kAvlGetWithParent.h

    r2 r7  
    3737 * The tree remains unchanged.
    3838 *
    39  * @returns   Pointer to the node holding the given key.
    40  * @param     ppTree    Pointer to the AVL-tree root node pointer.
    41  * @param     ppParent  Pointer to a variable which will hold the pointer to the partent node on
     39 * @returns Pointer to the node holding the given key.
     40 * @param   pRoot       Pointer to the AVL-tree root structure.
     41 * @param   ppParent    Pointer to a variable which will hold the pointer to the partent node on
    4242 *                      return. When no node is found, this will hold the last searched node.
    43  * @param     Key       Key value of the node which is to be found.
     43 * @param   Key         Key value of the node which is to be found.
    4444 */
    45 KAVL_DECL(KAVLNODE *) KAVL_FN(GetWithParent)(KAVLTREEPTR *ppTree, KAVLNODE **ppParent, KAVLKEY Key)
     45KAVL_DECL(KAVLNODE *) KAVL_FN(GetWithParent)(KAVLROOT *pRoot, KAVLNODE **ppParent, KAVLKEY Key)
    4646{
    47     register KAVLNODE *pNode = KAVL_GET_POINTER_NULL(ppTree);
    48     register KAVLNODE *pParent = NULL;
     47    register KAVLNODE *pNode;
     48    register KAVLNODE *pParent;
    4949
     50    KAVL_READ_LOCK(pRoot);
     51
     52    pParent = NULL;
     53    pNode = KAVL_GET_POINTER_NULL(&pRoot->mpRoot);
    5054    while (     pNode != NULL
    5155           &&   KAVL_NE(pNode->mKey, Key))
     
    5862    }
    5963
     64    KAVL_UNLOCK(pRoot);
     65
    6066    *ppParent = pParent;
    6167    return pNode;
  • trunk/include/k/kAvlTmpl/kAvlRemove2.h

    r2 r7  
    3737 *
    3838 * @returns Pointer to the removed node (NULL if not in the tree)
    39  * @param   ppTree      Pointer to Pointer to the tree root node.
     39 * @param   pRoot       Pointer to the AVL-tree root structure.
    4040 * @param   Key         The Key of which is to be found a best fitting match for..
    4141 *
     
    4343 *          easier to manage.
    4444 */
    45 KAVL_DECL(KAVLNODE *) KAVL_FN(Remove2)(KAVLTREEPTR *ppTree, KAVLNODE *pNode)
     45KAVL_DECL(KAVLNODE *) KAVL_FN(Remove2)(KAVLTROOT *pRoot, KAVLNODE *pNode)
    4646{
    4747#ifdef KAVL_EQUAL_ALLOWED
     
    5050     */
    5151    KAVLNODE *pParent;
    52     KAVLNODE *pCurNode = KAVL_FN(GetWithParent)(ppTree, pNode->mKey, &pParent);
     52    KAVLNODE *pCurNode = KAVL_FN(GetWithParent)(pRoot, pNode->mKey, &pParent);
    5353    if (!pCurNode)
    5454        return NULL;
     55    KAVL_WRITE_LOCK(pRoot); /** @todo the locking here isn't 100% sane. The only way to archive that is by no calling worker functions. */
    5556    if (pCurNode != pNode)
    5657    {
     
    6566                KAVL_SET_POINTER_NULL(&pCurNode->mpList, KAVL_GET_POINTER_NULL(&pNode->mpList));
    6667                pNode->mpList = KAVL_NULL;
     68                KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
     69                KAVL_WRITE_UNLOCK(pRoot);
    6770                return pNode;
    6871            }
    6972            pCurNode = pNext;
    7073        }
     74        KAVL_WRITE_UNLOCK(pRoot);
    7175        return NULL;
    7276    }
     
    8084     */
    8185    if (pNode->mpList == KAVL_NODE)
    82         KAVL_FN(Remove)(ppTree, pNode->mKey);
     86    {
     87        KAVL_WRITE_UNLOCK(pRoot);
     88        KAVL_FN(Remove)(pRoot, pNode->mKey);
     89    }
    8390    else
    8491    {
     
    105112        }
    106113        else
    107             KAVL_SET_POINTER(ppTree, pNewUs);
     114            KAVL_SET_POINTER(&pRoot->mpRoot, pNewUs);
     115
     116        KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
     117        KAVL_WRITE_UNLOCK(pRoot);
    108118    }
     119
    109120    return pNode;
    110121
     
    116127     * of wrong nodes but just uses this API for his convenience.
    117128     */
    118     KAVLNODE *pRemovedNode = KAVL_FN(Remove)(ppTree, pNode->mKey);
     129    KAVLNODE *pRemovedNode = KAVL_FN(Remove)(pRoot, pNode->mKey);
    119130    if (pRemovedNode == pNode)
    120131        return pRemovedNode;
    121132
    122     KAVL_FN(Insert)(ppTree, pRemovedNode);
     133    KAVL_FN(Insert)(pRoot, pRemovedNode);
    123134    return NULL;
    124135#endif
  • trunk/include/k/kAvlTmpl/kAvlRemoveBestFit.h

    r2 r7  
    3737 *
    3838 * @returns Pointer to the removed node.
    39  * @param   ppTree      Pointer to Pointer to the tree root node.
     39 * @param   pRoot       Pointer to the AVL-tree root structure.
    4040 * @param   Key         The Key of which is to be found a best fitting match for..
    4141 * @param   fAbove      K_TRUE:  Returned node is have the closest key to Key from above.
     
    4646 *          code size, and the likelyhood for bugs.
    4747 */
    48 KAVL_DECL(KAVLNODE *) KAVL_FN(RemoveBestFit)(KAVLTREEPTR *ppTree, KAVLKEY Key, KBOOL fAbove)
     48KAVL_DECL(KAVLNODE *) KAVL_FN(RemoveBestFit)(KAVLROOT *pRoot, KAVLKEY Key, KBOOL fAbove)
    4949{
    5050    /*
     
    5353     * removing the in-tree node as this is way cheaper.
    5454     */
    55     KAVLNODE *pNode = KAVL_FN(GetBestFit)(ppTree, Key, fAbove);
     55    KAVLNODE *pNode = KAVL_FN(GetBestFit)(pRoot, Key, fAbove);
    5656    if (pNode != NULL)
    5757    {
    5858#ifdef KAVL_EQUAL_ALLOWED
     59        KAVL_WRITE_LOCK(pRoot); /** @todo the locking isn't quite sane here. :-/ */
    5960        if (pNode->mpList != KAVL_NULL)
    6061        {
    6162            KAVLNODE *pRet = KAVL_GET_POINTER(&pNode->mpList);
    6263            KAVL_SET_POINTER_NULL(&pNode->mpList, &pRet->mpList);
     64            KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey);
     65            KAVL_WRITE_UNLOCK(pRoot);
    6366            return pRet;
    6467        }
     68        KAVL_WRITE_UNLOCK(pRoot);
    6569#endif
    66         pNode = KAVL_FN(Remove)(ppTree, pNode->mKey);
     70        pNode = KAVL_FN(Remove)(pRoot, pNode->mKey);
    6771    }
    6872    return pNode;
  • trunk/include/k/kAvlTmpl/kAvlUndef.h

    r2 r7  
    4141#undef KAVL_OFFSET
    4242#undef KAVL_STD_KEY_COMP
     43#undef KAVL_LOOKTHRU
     44#undef KAVL_LOOKTHRU_HASH
     45#undef KAVL_LOCKED
     46#undef KAVL_WRITE_LOCK
     47#undef KAVL_WRITE_UNLOCK
     48#undef KAVL_READ_LOCK
     49#undef KAVL_READ_UNLOCK
    4350#undef KAVLKEY
    4451#undef KAVLNODE
    4552#undef KAVLTREEPTR
     53#undef KAVLROOT
    4654#undef KAVL_FN
    4755#undef KAVL_TYPE
     
    5462#undef mpRight
    5563#undef mpList
     64#undef mpRoot
     65#undef maLookthru
    5666
    5767/*
  • trunk/kProfiler2/prfreader.cpp.h

    r2 r7  
    266266} KPRF_TYPE(,REPORTMODSEG), *KPRF_TYPE(P,REPORTMODSEG);
    267267
    268 /* Instantiate the AVL tree code. */
    269 #define KAVL_CHECK_FOR_EQUAL_INSERT
    270 #define KAVL_MAX_STACK          32
    271 #define KAVL_STD_KEY_COMP
    272 #define mKey                    offSegment
    273 #define KAVLKEY                 KDBGADDR
    274 #define KAVLNODE                KPRF_TYPE(,REPORTMODSEG)
    275 #define KAVL_FN(name)           KPRF_NAME(ReportTree ## name)
    276 #define KAVL_TYPE(prefix,name)  KPRF_TYPE(prefix, REPORTMODESEG ## name)
    277 #define KAVL_INT(name)          KPRF_NAME(REPORTMODESEGINT ## name)
    278 #define KAVL_DECL(type)         K_DECL_INLINE(type)
    279 #include <k/kAvlTmpl/kAvlBase.h>
    280 #include <k/kAvlTmpl/kAvlDestroy.h>
    281 #include <k/kAvlTmpl/kAvlGet.h>
    282 #include <k/kAvlTmpl/kAvlUndef.h>
    283 
    284268
    285269/**
     
    530514    /** The number of modules in the list. */
    531515    KU32                        cMods;
    532     /** The module segment tree. */
     516    /** The module segment tree. (Only kAvl cares about this.) */
    533517    KPRF_TYPE(P,REPORTMODSEG)   pModSegTree;
    534518    /** The number of module segments in the tree. */
     
    557541
    558542} KPRF_TYPE(,REPORT), *KPRF_TYPE(P,REPORT), **KPRF_TYPE(PP,REPORT);
     543
     544
     545/* Instantiate the AVL tree code. */
     546#define KAVL_CHECK_FOR_EQUAL_INSERT
     547#define KAVL_MAX_STACK          32
     548#define KAVL_STD_KEY_COMP
     549#define mKey                    offSegment
     550#define KAVLKEY                 KDBGADDR
     551#define KAVLNODE                KPRF_TYPE(,REPORTMODSEG)
     552#define mpRoot                  pModSegTree
     553#define KAVLROOT                KPRF_TYPE(,REPORT)
     554#define KAVL_FN(name)           KPRF_NAME(ReportTree ## name)
     555#define KAVL_TYPE(prefix,name)  KPRF_TYPE(prefix, REPORTMODESEG ## name)
     556#define KAVL_INT(name)          KPRF_NAME(REPORTMODESEGINT ## name)
     557#define KAVL_DECL(type)         K_DECL_INLINE(type)
     558#include <k/kAvlTmpl/kAvlBase.h>
     559#include <k/kAvlTmpl/kAvlDestroy.h>
     560#include <k/kAvlTmpl/kAvlGet.h>
     561#include <k/kAvlTmpl/kAvlUndef.h>
    559562
    560563
     
    592595    pReport->pFirstMod = NULL;
    593596    pReport->cMods = 0;
    594     pReport->pModSegTree = NULL;
     597    KPRF_NAME(ReportTreeInit)(pReport);
    595598    pReport->cModSegs = 0;
    596599    pReport->papSortedThreads = (KPRF_TYPE(P,REPORTTHREAD) *)((KU8 *)pReport + offSortedThreads);
     
    637640    }
    638641
    639     KPRF_NAME(ReportTreeDestroy)(&pReport->pModSegTree, KPRF_NAME(DeleteModSeg), NULL);
     642    KPRF_NAME(ReportTreeDestroy)(pReport, KPRF_NAME(DeleteModSeg), NULL);
    640643
    641644    /*
     
    688691        pSeg->cFunctions = 0;
    689692
    690         if (!KPRF_NAME(ReportTreeInsert)(&pReport->pModSegTree, pSeg))
     693        if (!KPRF_NAME(ReportTreeInsert)(pReport, pSeg))
    691694        {
    692695            free(pSeg);
     
    758761        pReport->papSortedFunctions[iFunc] = pReportFunc;
    759762        pReportFunc->pFunc = pFunc;
    760         pReportFunc->pModSeg = KPRF_NAME(ReportTreeGet)(&pReport->pModSegTree, pFunc->offModSeg);
     763        pReportFunc->pModSeg = KPRF_NAME(ReportTreeGet)(pReport, pFunc->offModSeg);
    761764        pReportFunc->pSym = NULL;
    762765        pReportFunc->pLine = NULL;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette