VirtualBox

Changeset 93711 in vbox for trunk/include/iprt/cpp


Ignore:
Timestamp:
Feb 12, 2022 1:58:36 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
149882
Message:

IPRT/hardavl: Added lookupMatchingOrLarger and lookupMatchingOrSmaller. bugref:10093

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cpp/hardavlrange.h

    r93709 r93711  
    461461
    462462    /**
     463     * Looks up node matching @a a_Key or if no exact match the closest smaller than it.
     464     *
     465     * @returns   IPRT status code.
     466     * @retval    VERR_NOT_FOUND if not found.
     467     *
     468     * @param     a_pAllocator  Pointer to the allocator.
     469     * @param     a_Key         A key value in the range of the desired node.
     470     * @param     a_ppFound     Where to return the pointer to the node.
     471     */
     472    int lookupMatchingOrSmaller(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, KeyType a_Key,
     473                                NodeType **a_ppFound) RT_NOEXCEPT
     474    {
     475        *a_ppFound = NULL;
     476
     477        NodeType *pNode = a_pAllocator->ptrFromInt(readIdx(&m_idxRoot));
     478        AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pNode), ("m_idxRoot=%#x pNode=%p\n", m_idxRoot, pNode),
     479                            m_cErrors++, a_pAllocator->ptrErrToStatus(pNode));
     480#ifdef RT_STRICT
     481        HardAvlStack  AVLStack;
     482        AVLStack.apidxEntries[0] = &m_idxRoot;
     483        AVLStack.cEntries = 1;
     484#endif
     485        unsigned  cDepth = 0;
     486        NodeType *pNodeLast = NULL;
     487        while (pNode)
     488        {
     489            RTHARDAVL_STRICT_CHECK_HEIGHTS(pNode, &AVLStack, AVLStack.cEntries);
     490            AssertReturn(cDepth <= kMaxHeight, VERR_HARDAVL_LOOKUP_TOO_DEEP);
     491            cDepth++;
     492
     493            if (isKeyInRange(a_Key, pNode->Key, pNode->KeyLast))
     494            {
     495                *a_ppFound = pNode;
     496                return VINF_SUCCESS;
     497            }
     498            if (isKeyGreater(pNode->Key, a_Key))
     499            {
     500#ifdef RT_STRICT
     501                AVLStack.apidxEntries[AVLStack.cEntries++] = &pNode->idxLeft;
     502#endif
     503                uint32_t const idxLeft = readIdx(&pNode->idxLeft);
     504                NodeType *pLeftNode = a_pAllocator->ptrFromInt(idxLeft);
     505                AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pLeftNode), ("idxLeft=%#x pLeftNode=%p\n", idxLeft, pLeftNode),
     506                                    m_cErrors++, a_pAllocator->ptrErrToStatus(pLeftNode));
     507                if (pLeftNode)
     508                    pNode = pLeftNode;
     509                else if (!pNodeLast)
     510                    break;
     511                else
     512                {
     513                    *a_ppFound = pNodeLast;
     514                    return VINF_SUCCESS;
     515                }
     516            }
     517            else
     518            {
     519#ifdef RT_STRICT
     520                AVLStack.apidxEntries[AVLStack.cEntries++] = &pNode->idxRight;
     521#endif
     522                uint32_t const idxRight = readIdx(&pNode->idxRight);
     523                NodeType *pRightNode = a_pAllocator->ptrFromInt(idxRight);
     524                AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pRightNode), ("idxRight=%#x pRightNode=%p\n", idxRight, pRightNode),
     525                                    m_cErrors++, a_pAllocator->ptrErrToStatus(pRightNode));
     526                if (pRightNode)
     527                {
     528                    pNodeLast = pNode;
     529                    pNode = pRightNode;
     530                }
     531                else
     532                {
     533                    *a_ppFound = pNode;
     534                    return VINF_SUCCESS;
     535                }
     536            }
     537        }
     538
     539        return VERR_NOT_FOUND;
     540    }
     541
     542    /**
     543     * Looks up node matching @a a_Key or if no exact match the closest larger than it.
     544     *
     545     * @returns   IPRT status code.
     546     * @retval    VERR_NOT_FOUND if not found.
     547     *
     548     * @param     a_pAllocator  Pointer to the allocator.
     549     * @param     a_Key         A key value in the range of the desired node.
     550     * @param     a_ppFound     Where to return the pointer to the node.
     551     */
     552    int lookupMatchingOrLarger(RTCHardAvlTreeSlabAllocator<NodeType> *a_pAllocator, KeyType a_Key,
     553                               NodeType **a_ppFound) RT_NOEXCEPT
     554    {
     555        *a_ppFound = NULL;
     556
     557        NodeType *pNode = a_pAllocator->ptrFromInt(readIdx(&m_idxRoot));
     558        AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pNode), ("m_idxRoot=%#x pNode=%p\n", m_idxRoot, pNode),
     559                            m_cErrors++, a_pAllocator->ptrErrToStatus(pNode));
     560#ifdef RT_STRICT
     561        HardAvlStack  AVLStack;
     562        AVLStack.apidxEntries[0] = &m_idxRoot;
     563        AVLStack.cEntries = 1;
     564#endif
     565        unsigned  cDepth = 0;
     566        NodeType *pNodeLast = NULL;
     567        while (pNode)
     568        {
     569            RTHARDAVL_STRICT_CHECK_HEIGHTS(pNode, &AVLStack, AVLStack.cEntries);
     570            AssertReturn(cDepth <= kMaxHeight, VERR_HARDAVL_LOOKUP_TOO_DEEP);
     571            cDepth++;
     572
     573            if (isKeyInRange(a_Key, pNode->Key, pNode->KeyLast))
     574            {
     575                *a_ppFound = pNode;
     576                return VINF_SUCCESS;
     577            }
     578            if (isKeyGreater(pNode->Key, a_Key))
     579            {
     580#ifdef RT_STRICT
     581                AVLStack.apidxEntries[AVLStack.cEntries++] = &pNode->idxLeft;
     582#endif
     583                uint32_t const idxLeft = readIdx(&pNode->idxLeft);
     584                NodeType *pLeftNode = a_pAllocator->ptrFromInt(idxLeft);
     585                AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pLeftNode), ("idxLeft=%#x pLeftNode=%p\n", idxLeft, pLeftNode),
     586                                    m_cErrors++, a_pAllocator->ptrErrToStatus(pLeftNode));
     587                if (pLeftNode)
     588                {
     589                    pNodeLast = pNode;
     590                    pNode = pLeftNode;
     591                }
     592                else
     593                {
     594                    *a_ppFound = pNode;
     595                    return VINF_SUCCESS;
     596                }
     597            }
     598            else
     599            {
     600#ifdef RT_STRICT
     601                AVLStack.apidxEntries[AVLStack.cEntries++] = &pNode->idxRight;
     602#endif
     603                uint32_t const idxRight = readIdx(&pNode->idxRight);
     604                NodeType *pRightNode = a_pAllocator->ptrFromInt(idxRight);
     605                AssertMsgReturnStmt(a_pAllocator->isPtrRetOkay(pRightNode), ("idxRight=%#x pRightNode=%p\n", idxRight, pRightNode),
     606                                    m_cErrors++, a_pAllocator->ptrErrToStatus(pRightNode));
     607                if (pRightNode)
     608                    pNode = pRightNode;
     609                else if (!pNodeLast)
     610                    break;
     611                else
     612                {
     613                    *a_ppFound = pNodeLast;
     614                    return VINF_SUCCESS;
     615                }
     616            }
     617        }
     618
     619        return VERR_NOT_FOUND;
     620    }
     621
     622    /**
    463623     * A callback for doWithAllFromLeft and doWithAllFromRight.
    464624     *
Note: See TracChangeset for help on using the changeset viewer.

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