Changeset 7 in kStuff
- Timestamp:
- Feb 4, 2008 2:08:02 AM (17 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/k/kAvlTmpl/kAvlBase.h
r2 r7 48 48 * 49 49 * \#define KAVL_MAX_STACK 50 * Use this to specify the max number of stack entries the stack will use when inserting51 * and removing nodes from the tree. The size should be something like50 * 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 52 52 * log2(<max nodes>) + 3 53 53 * Must be defined. … … 62 62 * the exact same distance. 63 63 * 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 * 64 92 * \#define KAVLKEY 65 93 * Define this to the name of the AVL key type. … … 68 96 * Define this to use the standard key compare macros. If not set all the 69 97 * 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 latter71 * 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. 72 100 * 73 101 * \#define KAVLNODE … … 83 111 * to KAVLNODE *. 84 112 * 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 * 85 120 * \#define KAVL_FN 86 121 * Use this to alter the names of the AVL functions. … … 160 195 #ifndef KAVLTREEPTR 161 196 # 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) 162 228 #endif 163 229 … … 219 285 typedef int (* KAVL_TYPE(PFN,CALLBACK))(KAVLNODE *, void *); 220 286 287 #ifdef KAVL_NEED_KAVLROOT 288 /** 289 * The AVL root structure. 290 */ 291 typedef struct 292 { 293 KAVLTREEPTR mpRoot; 294 # ifdef KAVL_LOOKTHRU 295 KAVLTREEPTR maLookthru[KAVL_LOOKTHRU]; 296 # endif 297 } KAVLROOT; 298 #endif 221 299 222 300 … … 343 421 344 422 /** 423 * Initializes the root of the AVL-tree. 424 * 425 * @param pTree Pointer to the root structure. 426 */ 427 KAVL_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 /** 345 442 * Inserts a node into the AVL-tree. 346 * @returns TRUE if inserted.347 * FALSE if node exists in tree.348 * @param p pTree 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. 350 447 * @sketch Find the location of the node (using binary tree algorithm.): 351 448 * LOOP until NULL leaf pointer … … 360 457 * Rebalance the tree. 361 458 */ 362 KAVL_DECL(KBOOL) KAVL_FN(Insert)(KAVL TREEPTR *ppTree, KAVLNODE *pNode)459 KAVL_DECL(KBOOL) KAVL_FN(Insert)(KAVLROOT *pRoot, KAVLNODE *pNode) 363 460 { 364 461 KAVL_INT(STACK) AVLStack; 365 KAVLTREEPTR *ppCurNode = ppTree;462 KAVLTREEPTR *ppCurNode = &pRoot->mpRoot; 366 463 register KAVLKEY Key = pNode->mKey; 367 464 #ifdef KAVL_RANGE … … 373 470 return false; 374 471 #endif 472 473 KAVL_WRITE_LOCK(pRoot); 375 474 376 475 AVLStack.cEntries = 0; … … 391 490 KAVL_SET_POINTER_NULL(&pNode->mpList, &pCurNode->mpList); 392 491 KAVL_SET_POINTER(&pCurNode->mpList, pNode); 492 KAVL_WRITE_UNLOCK(pRoot); 393 493 return K_TRUE; 394 494 } … … 396 496 #ifdef KAVL_CHECK_FOR_EQUAL_INSERT 397 497 if (KAVL_R_IS_INTERSECTING(pCurNode->mKey, Key, pCurNode->mKeyLast, KeyLast)) 498 { 499 KAVL_WRITE_UNLOCK(pRoot); 398 500 return K_FALSE; 501 } 399 502 #endif 400 503 if (KAVL_G(pCurNode->mKey, Key)) … … 412 515 413 516 KAVL_FN(Rebalance)(&AVLStack); 517 518 KAVL_WRITE_UNLOCK(pRoot); 414 519 return K_TRUE; 415 520 } … … 419 524 * Removes a node from the AVL-tree. 420 525 * @returns Pointer to the node. 421 * @param p pTree 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. 423 528 * @sketch Find the node which is to be removed: 424 529 * LOOP until not found … … 455 560 * return pointer to the removed node (if found). 456 561 */ 457 KAVL_DECL(KAVLNODE *) KAVL_FN(Remove)(KAVL TREEPTR *ppTree, KAVLKEY Key)562 KAVL_DECL(KAVLNODE *) KAVL_FN(Remove)(KAVLROOT *pRoot, KAVLKEY Key) 458 563 { 459 564 KAVL_INT(STACK) AVLStack; 460 KAVLTREEPTR *ppDeleteNode = ppTree;565 KAVLTREEPTR *ppDeleteNode = &pRoot->mpRoot; 461 566 register KAVLNODE *pDeleteNode; 567 568 KAVL_WRITE_LOCK(pRoot); 462 569 463 570 AVLStack.cEntries = 0; … … 465 572 { 466 573 if (*ppDeleteNode == KAVL_NULL) 574 { 575 KAVL_WRITE_UNLOCK(pRoot); 467 576 return NULL; 577 } 468 578 pDeleteNode = KAVL_GET_POINTER(ppDeleteNode); 469 579 … … 511 621 512 622 KAVL_FN(Rebalance)(&AVLStack); 623 624 KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pDeleteNode, Key); 625 626 KAVL_WRITE_UNLOCK(pRoot); 513 627 return pDeleteNode; 514 628 } -
trunk/include/k/kAvlTmpl/kAvlDestroy.h
r2 r7 41 41 * made on it. Note that the node we fail on will be considered dead and 42 42 * no action is taken to link it back into the tree. 43 * @param p pTree Pointer to the AVL-tree root node pointer.43 * @param pRoot Pointer to the AVL-tree root structure. 44 44 * @param pfnCallBack Pointer to callback function. 45 45 * @param pvUser User parameter passed on to the callback function. 46 46 */ 47 KAVL_DECL(int) KAVL_FN(Destroy)(KAVL TREEPTR *ppTree, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)47 KAVL_DECL(int) KAVL_FN(Destroy)(KAVLROOT *pRoot, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser) 48 48 { 49 #ifdef KAVL_LOOKTHRU 50 unsigned i; 51 #endif 49 52 unsigned cEntries; 50 53 KAVLNODE *apEntries[KAVL_MAX_STACK]; 51 54 int rc; 52 55 53 if (*ppTree == KAVL_NULL) 56 KAVL_WRITE_LOCK(pRoot); 57 if (pRoot->mpRoot == KAVL_NULL) 58 { 59 KAVL_WRITE_UNLOCK(pRoot); 54 60 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 55 70 56 71 cEntries = 1; 57 apEntries[0] = KAVL_GET_POINTER( ppTree);72 apEntries[0] = KAVL_GET_POINTER(&pRoot->mpRoot); 58 73 while (cEntries > 0) 59 74 { … … 80 95 rc = pfnCallBack(pEqual, pvUser); 81 96 if (rc) 97 { 98 KAVL_WRITE_UNLOCK(pRoot); 82 99 return rc; 100 } 83 101 } 84 102 #endif … … 96 114 } 97 115 else 98 *ppTree= KAVL_NULL;116 pRoot->mpRoot = KAVL_NULL; 99 117 100 118 kHlpAssert(pNode->mpLeft == KAVL_NULL); … … 102 120 rc = pfnCallBack(pNode, pvUser); 103 121 if (rc) 122 { 123 KAVL_WRITE_UNLOCK(pRoot); 104 124 return rc; 125 } 105 126 } 106 127 } /* while */ 107 kHlpAssert( *ppTree== KAVL_NULL);128 kHlpAssert(pRoot->mpRoot == KAVL_NULL); 108 129 130 KAVL_WRITE_UNLOCK(pRoot); 109 131 return 0; 110 132 } -
trunk/include/k/kAvlTmpl/kAvlDoWithAll.h
r2 r7 43 43 KAVLNODE *aEntries[KAVL_MAX_STACK]; 44 44 char achFlags[KAVL_MAX_STACK]; 45 KAVLROOT pRoot; 45 46 } KAVL_INT(STACK2); 46 47 … … 50 51 * 51 52 * @returns 0 on success. Return from callback on failure. 52 * @param p pTree Pointer to the AVL-tree root node pointer.53 * @param pRoot Pointer to the AVL-tree root structure. 53 54 * @param fFromLeft K_TRUE: Left to right. 54 55 * K_FALSE: Right to left. … … 56 57 * @param pvUser User parameter passed on to the callback function. 57 58 */ 58 KAVL_DECL(int) KAVL_FN(DoWithAll)(KAVL TREEPTR *ppTree, KBOOL fFromLeft, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser)59 KAVL_DECL(int) KAVL_FN(DoWithAll)(KAVLROOT *pRoot, KBOOL fFromLeft, KAVL_TYPE(PFN,CALLBACK) pfnCallBack, void *pvUser) 59 60 { 60 61 KAVL_INT(STACK2) AVLStack; … … 65 66 int rc; 66 67 67 if (*ppTree == KAVL_NULL) 68 KAVL_READ_LOCK(pRoot); 69 if (pRoot->mpRoot == KAVL_NULL) 70 { 71 KAVL_READ_UNLOCK(pRoot); 68 72 return 0; 73 } 69 74 70 75 AVLStack.cEntries = 1; 71 76 AVLStack.achFlags[0] = 0; 72 AVLStack.aEntries[0] = KAVL_GET_POINTER( ppTree);77 AVLStack.aEntries[0] = KAVL_GET_POINTER(&pRoot->mpRoot); 73 78 74 79 if (fFromLeft) … … 99 104 rc = pfnCallBack(pEqual, pvUser); 100 105 if (rc) 106 { 107 KAVL_READ_UNLOCK(pRoot); 101 108 return rc; 109 } 102 110 } 103 111 #endif … … 139 147 rc = pfnCallBack(pEqual, pvUser); 140 148 if (rc) 149 { 150 KAVL_READ_UNLOCK(pRoot); 141 151 return rc; 152 } 142 153 } 143 154 #endif … … 153 164 } 154 165 166 KAVL_READ_UNLOCK(pRoot); 155 167 return 0; 156 168 } -
trunk/include/k/kAvlTmpl/kAvlEnum.h
r2 r7 51 51 52 52 /** 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 */ 61 KAVL_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 /** 53 71 * Get the next node in the tree enumeration. 54 72 * … … 56 74 * chain like the DoWithAll function does. This may be changed later. 57 75 * 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. 59 79 * @param pEnumData Pointer to enumeration control data. 60 80 */ … … 130 150 } 131 151 152 /* 153 * Call EndEnum. 154 */ 155 KAVL_FN(EndEnum)(pEnumData); 132 156 return NULL; 133 157 } … … 137 161 * Starts an enumeration of all nodes in the given AVL tree. 138 162 * 139 * The current implementation of this function will lnot walk the mpList163 * The current implementation of this function will not walk the mpList 140 164 * chain like the DoWithAll function does. This may be changed later. 141 165 * 142 166 * @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. 147 173 */ 148 KAVL_DECL(KAVLNODE *) KAVL_FN(BeginEnum)(KAVL TREEPTR *ppTree, KAVL_TYPE(,ENUMDATA) *pEnumData, KBOOL fFromLeft)174 KAVL_DECL(KAVLNODE *) KAVL_FN(BeginEnum)(KAVLROOT *pRoot, KAVL_TYPE(,ENUMDATA) *pEnumData, KBOOL fFromLeft) 149 175 { 150 if (*ppTree != KAVL_NULL) 176 KAVL_READ_LOCK(pRoot); 177 pEnumData->pRoot = pRoot; 178 if (pRoot->mpRoot != KAVL_NULL) 151 179 { 152 180 pEnumData->fFromLeft = fFromLeft; 153 181 pEnumData->cEntries = 1; 154 pEnumData->aEntries[0] = KAVL_GET_POINTER(p pTree);182 pEnumData->aEntries[0] = KAVL_GET_POINTER(pRoot->mpRoot); 155 183 pEnumData->achFlags[0] = 0; 156 184 } -
trunk/include/k/kAvlTmpl/kAvlGet.h
r2 r7 36 36 * Gets a node from the tree (does not remove it!) 37 37 * 38 * @returns 39 * @param ppTree Pointer to the AVL-tree root node pointer.40 * @param KeyKey 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. 41 41 */ 42 KAVL_DECL(KAVLNODE *) KAVL_FN(Get)(KAVL TREEPTR *ppTree, KAVLKEY Key)42 KAVL_DECL(KAVLNODE *) KAVL_FN(Get)(KAVLROOT *pRoot, KAVLKEY Key) 43 43 { 44 44 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); 46 53 return NULL; 54 } 47 55 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 50 61 { 51 if (KAVL_G(pNode->mKey, Key)) 62 pNode = KAVL_GET_POINTER(&pRoot->mpRoot); 63 while (KAVL_NE(pNode->mKey, Key)) 52 64 { 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 } 56 83 } 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 63 88 } 89 90 KAVL_READ_UNLOCK(pRoot); 64 91 return pNode; 65 92 } -
trunk/include/k/kAvlTmpl/kAvlGetBestFit.h
r2 r7 37 37 * 38 38 * @returns Pointer to the best fitting node found. 39 * @param p pTree 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. 43 43 * @sketch The best fitting node is always located in the searchpath above you. 44 44 * >= (above): The node where you last turned left. 45 45 * <= (below): the node where you last turned right. 46 46 */ 47 KAVL_DECL(KAVLNODE *) KAVL_FN(GetBestFit)(KAVL TREEPTR *ppTree, KAVLKEY Key, KBOOL fAbove)47 KAVL_DECL(KAVLNODE *) KAVL_FN(GetBestFit)(KAVLROOT *pRoot, KAVLKEY Key, KBOOL fAbove) 48 48 { 49 49 register KAVLNODE *pNode; 50 50 KAVLNODE *pNodeLast; 51 51 52 if (*ppTree == KAVL_NULL) 52 KAVL_READ_LOCK(pLook); 53 if (pRoot->mpRoot == KAVL_NULL) 54 { 55 KAVL_READ_UNLOCK(pLook); 53 56 return NULL; 57 } 54 58 55 pNode = KAVL_GET_POINTER( ppTree);59 pNode = KAVL_GET_POINTER(&pRoot->mpRoot); 56 60 pNodeLast = NULL; 57 61 if (fAbove) … … 62 66 { 63 67 if (pNode->mpLeft == KAVL_NULL) 68 { 69 KAVL_READ_UNLOCK(pLook); 64 70 return pNode; 71 } 65 72 pNodeLast = pNode; 66 73 pNode = KAVL_GET_POINTER(&pNode->mpLeft); … … 69 76 { 70 77 if (pNode->mpRight == KAVL_NULL) 78 { 79 KAVL_READ_UNLOCK(pLook); 71 80 return pNodeLast; 81 } 72 82 pNode = KAVL_GET_POINTER(&pNode->mpRight); 73 83 } … … 81 91 { 82 92 if (pNode->mpLeft == KAVL_NULL) 93 { 94 KAVL_READ_UNLOCK(pLook); 83 95 return pNodeLast; 96 } 84 97 pNode = KAVL_GET_POINTER(&pNode->mpLeft); 85 98 } … … 87 100 { 88 101 if (pNode->mpRight == KAVL_NULL) 102 { 103 KAVL_READ_UNLOCK(pLook); 89 104 return pNode; 105 } 90 106 pNodeLast = pNode; 91 107 pNode = KAVL_GET_POINTER(&pNode->mpRight); … … 95 111 96 112 /* perfect match or nothing. */ 113 KAVL_READ_UNLOCK(pLook); 97 114 return pNode; 98 115 } -
trunk/include/k/kAvlTmpl/kAvlGetWithParent.h
r2 r7 37 37 * The tree remains unchanged. 38 38 * 39 * @returns 40 * @param ppTree Pointer to the AVL-tree root node pointer.41 * @param ppParentPointer to a variable which will hold the pointer to the partent node on39 * @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 42 42 * return. When no node is found, this will hold the last searched node. 43 * @param KeyKey value of the node which is to be found.43 * @param Key Key value of the node which is to be found. 44 44 */ 45 KAVL_DECL(KAVLNODE *) KAVL_FN(GetWithParent)(KAVL TREEPTR *ppTree, KAVLNODE **ppParent, KAVLKEY Key)45 KAVL_DECL(KAVLNODE *) KAVL_FN(GetWithParent)(KAVLROOT *pRoot, KAVLNODE **ppParent, KAVLKEY Key) 46 46 { 47 register KAVLNODE *pNode = KAVL_GET_POINTER_NULL(ppTree);48 register KAVLNODE *pParent = NULL;47 register KAVLNODE *pNode; 48 register KAVLNODE *pParent; 49 49 50 KAVL_READ_LOCK(pRoot); 51 52 pParent = NULL; 53 pNode = KAVL_GET_POINTER_NULL(&pRoot->mpRoot); 50 54 while ( pNode != NULL 51 55 && KAVL_NE(pNode->mKey, Key)) … … 58 62 } 59 63 64 KAVL_UNLOCK(pRoot); 65 60 66 *ppParent = pParent; 61 67 return pNode; -
trunk/include/k/kAvlTmpl/kAvlRemove2.h
r2 r7 37 37 * 38 38 * @returns Pointer to the removed node (NULL if not in the tree) 39 * @param p pTree Pointer to Pointer to the tree root node.39 * @param pRoot Pointer to the AVL-tree root structure. 40 40 * @param Key The Key of which is to be found a best fitting match for.. 41 41 * … … 43 43 * easier to manage. 44 44 */ 45 KAVL_DECL(KAVLNODE *) KAVL_FN(Remove2)(KAVLTR EEPTR *ppTree, KAVLNODE *pNode)45 KAVL_DECL(KAVLNODE *) KAVL_FN(Remove2)(KAVLTROOT *pRoot, KAVLNODE *pNode) 46 46 { 47 47 #ifdef KAVL_EQUAL_ALLOWED … … 50 50 */ 51 51 KAVLNODE *pParent; 52 KAVLNODE *pCurNode = KAVL_FN(GetWithParent)(p pTree, pNode->mKey, &pParent);52 KAVLNODE *pCurNode = KAVL_FN(GetWithParent)(pRoot, pNode->mKey, &pParent); 53 53 if (!pCurNode) 54 54 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. */ 55 56 if (pCurNode != pNode) 56 57 { … … 65 66 KAVL_SET_POINTER_NULL(&pCurNode->mpList, KAVL_GET_POINTER_NULL(&pNode->mpList)); 66 67 pNode->mpList = KAVL_NULL; 68 KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey); 69 KAVL_WRITE_UNLOCK(pRoot); 67 70 return pNode; 68 71 } 69 72 pCurNode = pNext; 70 73 } 74 KAVL_WRITE_UNLOCK(pRoot); 71 75 return NULL; 72 76 } … … 80 84 */ 81 85 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 } 83 90 else 84 91 { … … 105 112 } 106 113 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); 108 118 } 119 109 120 return pNode; 110 121 … … 116 127 * of wrong nodes but just uses this API for his convenience. 117 128 */ 118 KAVLNODE *pRemovedNode = KAVL_FN(Remove)(p pTree, pNode->mKey);129 KAVLNODE *pRemovedNode = KAVL_FN(Remove)(pRoot, pNode->mKey); 119 130 if (pRemovedNode == pNode) 120 131 return pRemovedNode; 121 132 122 KAVL_FN(Insert)(p pTree, pRemovedNode);133 KAVL_FN(Insert)(pRoot, pRemovedNode); 123 134 return NULL; 124 135 #endif -
trunk/include/k/kAvlTmpl/kAvlRemoveBestFit.h
r2 r7 37 37 * 38 38 * @returns Pointer to the removed node. 39 * @param p pTree Pointer to Pointer to the tree root node.39 * @param pRoot Pointer to the AVL-tree root structure. 40 40 * @param Key The Key of which is to be found a best fitting match for.. 41 41 * @param fAbove K_TRUE: Returned node is have the closest key to Key from above. … … 46 46 * code size, and the likelyhood for bugs. 47 47 */ 48 KAVL_DECL(KAVLNODE *) KAVL_FN(RemoveBestFit)(KAVL TREEPTR *ppTree, KAVLKEY Key, KBOOL fAbove)48 KAVL_DECL(KAVLNODE *) KAVL_FN(RemoveBestFit)(KAVLROOT *pRoot, KAVLKEY Key, KBOOL fAbove) 49 49 { 50 50 /* … … 53 53 * removing the in-tree node as this is way cheaper. 54 54 */ 55 KAVLNODE *pNode = KAVL_FN(GetBestFit)(p pTree, Key, fAbove);55 KAVLNODE *pNode = KAVL_FN(GetBestFit)(pRoot, Key, fAbove); 56 56 if (pNode != NULL) 57 57 { 58 58 #ifdef KAVL_EQUAL_ALLOWED 59 KAVL_WRITE_LOCK(pRoot); /** @todo the locking isn't quite sane here. :-/ */ 59 60 if (pNode->mpList != KAVL_NULL) 60 61 { 61 62 KAVLNODE *pRet = KAVL_GET_POINTER(&pNode->mpList); 62 63 KAVL_SET_POINTER_NULL(&pNode->mpList, &pRet->mpList); 64 KAVL_LOOKTHRU_INVALIDATE_NODE(pRoot, pNode, pNode->mKey); 65 KAVL_WRITE_UNLOCK(pRoot); 63 66 return pRet; 64 67 } 68 KAVL_WRITE_UNLOCK(pRoot); 65 69 #endif 66 pNode = KAVL_FN(Remove)(p pTree, pNode->mKey);70 pNode = KAVL_FN(Remove)(pRoot, pNode->mKey); 67 71 } 68 72 return pNode; -
trunk/include/k/kAvlTmpl/kAvlUndef.h
r2 r7 41 41 #undef KAVL_OFFSET 42 42 #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 43 50 #undef KAVLKEY 44 51 #undef KAVLNODE 45 52 #undef KAVLTREEPTR 53 #undef KAVLROOT 46 54 #undef KAVL_FN 47 55 #undef KAVL_TYPE … … 54 62 #undef mpRight 55 63 #undef mpList 64 #undef mpRoot 65 #undef maLookthru 56 66 57 67 /* -
trunk/kProfiler2/prfreader.cpp.h
r2 r7 266 266 } KPRF_TYPE(,REPORTMODSEG), *KPRF_TYPE(P,REPORTMODSEG); 267 267 268 /* Instantiate the AVL tree code. */269 #define KAVL_CHECK_FOR_EQUAL_INSERT270 #define KAVL_MAX_STACK 32271 #define KAVL_STD_KEY_COMP272 #define mKey offSegment273 #define KAVLKEY KDBGADDR274 #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 284 268 285 269 /** … … 530 514 /** The number of modules in the list. */ 531 515 KU32 cMods; 532 /** The module segment tree. */516 /** The module segment tree. (Only kAvl cares about this.) */ 533 517 KPRF_TYPE(P,REPORTMODSEG) pModSegTree; 534 518 /** The number of module segments in the tree. */ … … 557 541 558 542 } 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> 559 562 560 563 … … 592 595 pReport->pFirstMod = NULL; 593 596 pReport->cMods = 0; 594 pReport->pModSegTree = NULL;597 KPRF_NAME(ReportTreeInit)(pReport); 595 598 pReport->cModSegs = 0; 596 599 pReport->papSortedThreads = (KPRF_TYPE(P,REPORTTHREAD) *)((KU8 *)pReport + offSortedThreads); … … 637 640 } 638 641 639 KPRF_NAME(ReportTreeDestroy)( &pReport->pModSegTree, KPRF_NAME(DeleteModSeg), NULL);642 KPRF_NAME(ReportTreeDestroy)(pReport, KPRF_NAME(DeleteModSeg), NULL); 640 643 641 644 /* … … 688 691 pSeg->cFunctions = 0; 689 692 690 if (!KPRF_NAME(ReportTreeInsert)( &pReport->pModSegTree, pSeg))693 if (!KPRF_NAME(ReportTreeInsert)(pReport, pSeg)) 691 694 { 692 695 free(pSeg); … … 758 761 pReport->papSortedFunctions[iFunc] = pReportFunc; 759 762 pReportFunc->pFunc = pFunc; 760 pReportFunc->pModSeg = KPRF_NAME(ReportTreeGet)( &pReport->pModSegTree, pFunc->offModSeg);763 pReportFunc->pModSeg = KPRF_NAME(ReportTreeGet)(pReport, pFunc->offModSeg); 761 764 pReportFunc->pSym = NULL; 762 765 pReportFunc->pLine = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.