Changeset 7 for trunk/include/k/kAvlTmpl/kAvlBase.h
- Timestamp:
- Feb 4, 2008, 3:08:02 AM (18 years ago)
- File:
-
- 1 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 }
Note:
See TracChangeset
for help on using the changeset viewer.