Changeset 93709 in vbox
- Timestamp:
- Feb 11, 2022 11:09:11 PM (3 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/cpp/hardavlrange.h
r93695 r93709 128 128 * Read an index value trying to prevent the compiler from re-reading it. 129 129 */ 130 DECL_FORCE_INLINE(uint32_t) readIdx(uint32_t volatile *pidx) 130 DECL_FORCE_INLINE(uint32_t) readIdx(uint32_t volatile *pidx) RT_NOEXCEPT 131 131 { 132 132 uint32_t idx = *pidx; … … 135 135 } 136 136 137 138 RTCHardAvlRangeTree() 137 RTCHardAvlRangeTree() RT_NOEXCEPT 139 138 : m_idxRoot(0) 140 139 , m_cErrors(0) 141 140 { } 142 141 143 RTCHardAvlRangeTree(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator) 144 : m_idxRoot(a_pAllocator->kNilIndex) 145 , m_cErrors(0) 146 { } 142 RTCHardAvlRangeTree(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator) RT_NOEXCEPT 143 { 144 initWithAllocator(a_pAllocator); 145 } 146 147 void initWithAllocator(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator) RT_NOEXCEPT 148 { 149 m_idxRoot = a_pAllocator->kNilIndex; 150 m_cErrors = 0; 151 } 147 152 148 153 /** … … 169 174 * @endcode 170 175 */ 171 int insert(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, NodeType *a_pNode) 176 int insert(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, NodeType *a_pNode) RT_NOEXCEPT 172 177 { 173 178 KeyType const Key = a_pNode->Key; … … 269 274 * @endcode 270 275 */ 271 int remove(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, KeyType a_Key, NodeType **a_ppRemoved) 276 int remove(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, KeyType a_Key, NodeType **a_ppRemoved) RT_NOEXCEPT 272 277 { 273 278 *a_ppRemoved = NULL; … … 406 411 * @param a_ppFound Where to return the pointer to the node. 407 412 */ 408 int lookup(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, KeyType a_Key, NodeType **a_ppFound) 413 int lookup(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, KeyType a_Key, NodeType **a_ppFound) RT_NOEXCEPT 409 414 { 410 415 *a_ppFound = NULL; … … 475 480 * @param a_pfnCallBack Pointer to callback function. 476 481 * @param a_pvUser Callback user argument. 482 * 483 * @note This is very similar code to doWithAllFromRight() and destroy(). 477 484 */ 478 int doWithAllFromLeft(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, PFNCALLBACK a_pfnCallBack, void *a_pvUser) 485 int doWithAllFromLeft(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, 486 PFNCALLBACK a_pfnCallBack, void *a_pvUser) RT_NOEXCEPT 479 487 { 480 488 NodeType *pNode = a_pAllocator->ptrFromInt(readIdx(&m_idxRoot)); … … 575 583 576 584 /** 585 * Iterates thru all nodes in the tree from right (larger) to left (smaller). 586 * 587 * @returns IPRT status code. 588 * 589 * @param a_pAllocator Pointer to the allocator. 590 * @param a_pfnCallBack Pointer to callback function. 591 * @param a_pvUser Callback user argument. 592 * 593 * @note This is very similar code to doWithAllFromLeft() and destroy(). 594 */ 595 int doWithAllFromRight(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, 596 PFNCALLBACK a_pfnCallBack, void *a_pvUser) RT_NOEXCEPT 597 { 598 NodeType *pNode = a_pAllocator->ptrFromInt(readIdx(&m_idxRoot)); 599 AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pNode), ("m_idxRoot=%#x pNode=%p\n", m_idxRoot, pNode), 600 m_cErrors++, a_pAllocator->ptrErrToStatus(pNode)); 601 if (!pNode) 602 return VINF_SUCCESS; 603 604 /* 605 * We simulate recursive calling here. For safety reasons, we do not 606 * pop before going down the right tree like the original code did. 607 */ 608 uint32_t cNodesLeft = a_pAllocator->m_cNodes; 609 NodeType *apEntries[kMaxStack]; 610 uint8_t abState[kMaxStack]; 611 unsigned cEntries = 1; 612 abState[0] = 0; 613 apEntries[0] = pNode; 614 while (cEntries > 0) 615 { 616 pNode = apEntries[cEntries - 1]; 617 switch (abState[cEntries - 1]) 618 { 619 /* Go right. */ 620 case 0: 621 { 622 abState[cEntries - 1] = 1; 623 624 NodeType * const pRightNode = a_pAllocator->ptrFromInt(readIdx(&pNode->idxRight)); 625 AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pRightNode), 626 ("idxRight=%#x pRightNode=%p\n", pNode->idxRight, pRightNode), 627 m_cErrors++, a_pAllocator->ptrErrToStatus(pRightNode)); 628 if (pRightNode) 629 { 630 #if RT_GNUC_PREREQ_EX(4,7, 1) /* 32-bit 4.4.7 has trouble, dunno when it started working exactly */ 631 AssertCompile(kMaxStack > 6); 632 #endif 633 AssertMsgReturnStmt(cEntries < RT_ELEMENTS(apEntries), 634 ("%p[%#x] %p %p %p %p %p %p\n", pRightNode, pNode->idxRight, apEntries[kMaxStack - 1], 635 apEntries[kMaxStack - 2], apEntries[kMaxStack - 3], apEntries[kMaxStack - 4], 636 apEntries[kMaxStack - 5], apEntries[kMaxStack - 6]), 637 m_cErrors++, VERR_HARDAVL_STACK_OVERFLOW); 638 apEntries[cEntries] = pRightNode; 639 abState[cEntries] = 0; 640 cEntries++; 641 642 AssertReturn(cNodesLeft > 0, VERR_HARDAVL_TRAVERSED_TOO_MANY_NODES); 643 cNodesLeft--; 644 break; 645 } 646 RT_FALL_THROUGH(); 647 } 648 649 /* center then left. */ 650 case 1: 651 { 652 abState[cEntries - 1] = 2; 653 654 RTHARDAVL_STRICT_CHECK_HEIGHTS(pNode, NULL, 0); 655 656 int rc = a_pfnCallBack(pNode, a_pvUser); 657 if (rc != VINF_SUCCESS) 658 return rc; 659 660 NodeType * const pLeftNode = a_pAllocator->ptrFromInt(readIdx(&pNode->idxLeft)); 661 AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pLeftNode), 662 ("idxLeft=%#x pLeftNode=%p\n", pNode->idxLeft, pLeftNode), 663 m_cErrors++, a_pAllocator->ptrErrToStatus(pLeftNode)); 664 if (pLeftNode) 665 { 666 #if RT_GNUC_PREREQ_EX(4,7, 1) /* 32-bit 4.4.7 has trouble, dunno when it started working exactly */ 667 AssertCompile(kMaxStack > 6); 668 #endif 669 AssertMsgReturnStmt(cEntries < RT_ELEMENTS(apEntries), 670 ("%p[%#x] %p %p %p %p %p %p\n", pLeftNode, pNode->idxLeft, apEntries[kMaxStack - 1], 671 apEntries[kMaxStack - 2], apEntries[kMaxStack - 3], apEntries[kMaxStack - 4], 672 apEntries[kMaxStack - 5], apEntries[kMaxStack - 6]), 673 m_cErrors++, VERR_HARDAVL_STACK_OVERFLOW); 674 apEntries[cEntries] = pLeftNode; 675 abState[cEntries] = 0; 676 cEntries++; 677 678 AssertReturn(cNodesLeft > 0, VERR_HARDAVL_TRAVERSED_TOO_MANY_NODES); 679 cNodesLeft--; 680 break; 681 } 682 RT_FALL_THROUGH(); 683 } 684 685 default: 686 /* pop it. */ 687 cEntries -= 1; 688 break; 689 } 690 } 691 return VINF_SUCCESS; 692 } 693 694 /** 577 695 * A callback for destroy to do additional cleanups before the node is freed. 578 696 * … … 599 717 * @note This is mostly the same code as the doWithAllFromLeft(). 600 718 */ 601 int destroy(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, PFNDESTROYCALLBACK a_pfnCallBack = NULL, void *a_pvUser = NULL) 719 int destroy(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, 720 PFNDESTROYCALLBACK a_pfnCallBack = NULL, void *a_pvUser = NULL) RT_NOEXCEPT 602 721 { 603 722 NodeType *pNode = a_pAllocator->ptrFromInt(readIdx(&m_idxRoot)); … … 707 826 * @retval UINT8_MAX if bogus tree. 708 827 */ 709 uint8_t getHeight(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator) 828 uint8_t getHeight(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator) RT_NOEXCEPT 710 829 { 711 830 NodeType *pNode = a_pAllocator->ptrFromInt(readIdx(&m_idxRoot)); … … 719 838 #ifdef RT_STRICT 720 839 721 static void dumpStack(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, HardAvlStack const *pStack) 840 static void dumpStack(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, HardAvlStack const *pStack) RT_NOEXCEPT 722 841 { 723 842 uint32_t const * const *paidx = pStack->apidxEntries; … … 735 854 736 855 static void printTree(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, uint32_t a_idxRoot, 737 unsigned a_uLevel = 0, unsigned a_uMaxLevel = 8, const char *a_pszDir = "") 856 unsigned a_uLevel = 0, unsigned a_uMaxLevel = 8, const char *a_pszDir = "") RT_NOEXCEPT 738 857 { 739 858 if (a_idxRoot == a_pAllocator->kNilIndex) … … 811 930 * @internal 812 931 */ 813 int i_rebalance(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, HardAvlStack *a_pStack, bool a_fLog = false) 932 int i_rebalance(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, HardAvlStack *a_pStack, bool a_fLog = false) RT_NOEXCEPT 814 933 { 815 934 RT_NOREF(a_fLog); -
trunk/src/VBox/Runtime/testcase/tstRTAvl.cpp
r93694 r93709 1124 1124 1125 1125 1126 static DECLCALLBACK(int) hardAvlRangeTreeGCPhysEnumCallbackDescBy4(TESTNODE *pNode, void *pvUser) 1127 { 1128 PRTGCPHYS pExpect = (PRTGCPHYS)pvUser; 1129 if (pNode->Key != *pExpect) 1130 RTTestIFailed("Key=%RGp, expected %RGp\n", pNode->Key, *pExpect); 1131 *pExpect = pNode->Key - 4; 1132 return VINF_SUCCESS; 1133 } 1134 1135 1126 1136 static DECLCALLBACK(int) hardAvlRangeTreeGCPhysEnumCallbackCount(TESTNODE *pNode, void *pvUser) 1127 1137 { … … 1316 1326 if (rc != VINF_SUCCESS) 1317 1327 RTTestIFailed("enumeration after linear insert failed: %Rrc", rc); 1328 1329 Expect -= 4; 1330 rc = Tree.doWithAllFromRight(&Allocator, hardAvlRangeTreeGCPhysEnumCallbackDescBy4, &Expect); 1331 if (rc != VINF_SUCCESS) 1332 RTTestIFailed("enumeration after linear insert failed: %Rrc", rc); 1318 1333 } 1319 1334
Note:
See TracChangeset
for help on using the changeset viewer.