diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-05-26 15:19:42 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-05-28 16:00:09 +0200 |
commit | 87a932120d5f146933ed3bcc16c0f47dab90fd4b (patch) | |
tree | 6022b3ff930f5931c39ff29f47259ffc704f4dd5 /svl | |
parent | 9ea767cb568cef1b142190d2adb0e301baa382e2 (diff) |
ofz#24932-1 speed up GetItemState when iterating
by having SfxWhichIter track the current position in
the m_ppItems table, which means GetItemState does
not need to traverse the ranges table to find the
item position.
shaves 75% off the time of
./instdir/program/soffice.bin --calc --convert-to pdf
~/Downloads/ofz24932-1.rtf
Change-Id: Ib5fe61c75ca05bc2f1932e84b57ccfa55f8b7f74
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135023
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'svl')
-rw-r--r-- | svl/source/items/itemset.cxx | 55 | ||||
-rw-r--r-- | svl/source/items/whiter.cxx | 49 |
2 files changed, 70 insertions, 34 deletions
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx index 2d90ab16eac7..c96bac69c54d 100644 --- a/svl/source/items/itemset.cxx +++ b/svl/source/items/itemset.cxx @@ -309,40 +309,65 @@ SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich, bool bSrchInParent, const SfxPoolItem **ppItem ) const { + return GetItemStateImpl(nWhich, bSrchInParent, ppItem, std::nullopt); +} + +SfxItemState SfxItemSet::GetItemStateImpl( sal_uInt16 nWhich, + bool bSrchInParent, + const SfxPoolItem **ppItem, + std::optional<sal_uInt16> oItemsOffsetHint) const +{ // Find the range in which the Which is located const SfxItemSet* pCurrentSet = this; SfxItemState eRet = SfxItemState::UNKNOWN; do { - SfxPoolItem const** ppFnd = pCurrentSet->m_ppItems; - for (const WhichPair& rPair : pCurrentSet->m_pWhichRanges) + SfxPoolItem const** pFoundOne = nullptr; + if (oItemsOffsetHint) + { + pFoundOne = pCurrentSet->m_ppItems + *oItemsOffsetHint; + assert(!*pFoundOne || IsInvalidItem(*pFoundOne) || (*pFoundOne)->IsVoidItem() || (*pFoundOne)->Which() == nWhich); + oItemsOffsetHint.reset(); // in case we need to search parent + } + else { - if ( rPair.first <= nWhich && nWhich <= rPair.second ) + SfxPoolItem const** ppFnd = pCurrentSet->m_ppItems; + for (const WhichPair& rPair : pCurrentSet->m_pWhichRanges) { - // Within this range - ppFnd += nWhich - rPair.first; - if ( !*ppFnd ) + if ( rPair.first <= nWhich && nWhich <= rPair.second ) { - eRet = SfxItemState::DEFAULT; - if( !bSrchInParent ) - return eRet; // Not present - break; // Keep searching in the parents! + // Within this range + pFoundOne = ppFnd + nWhich - rPair.first; + break; } + ppFnd += rPair.second - rPair.first + 1; + } + } - if ( IsInvalidItem(*ppFnd) ) + if (pFoundOne) + { + if ( !*pFoundOne ) + { + eRet = SfxItemState::DEFAULT; + if( !bSrchInParent ) + return eRet; // Not present + // Keep searching in the parents! + } + else + { + if ( IsInvalidItem(*pFoundOne) ) // Different ones are present return SfxItemState::DONTCARE; - if ( (*ppFnd)->IsVoidItem() ) + if ( (*pFoundOne)->IsVoidItem() ) return SfxItemState::DISABLED; if (ppItem) { - *ppItem = *ppFnd; + *ppItem = *pFoundOne; } return SfxItemState::SET; } - ppFnd += rPair.second - rPair.first + 1; } if (!bSrchInParent) break; @@ -726,7 +751,7 @@ bool SfxItemSet::Set continue; } const SfxPoolItem* pItem; - if( SfxItemState::SET == rSet.GetItemState( nWhich1, true, &pItem ) ) + if( SfxItemState::SET == aIter2.GetItemState( true, &pItem ) ) bRet |= nullptr != Put( *pItem, pItem->Which() ); nWhich1 = aIter1.NextWhich(); nWhich2 = aIter2.NextWhich(); diff --git a/svl/source/items/whiter.cxx b/svl/source/items/whiter.cxx index 59f2790a530c..707349c70ea5 100644 --- a/svl/source/items/whiter.cxx +++ b/svl/source/items/whiter.cxx @@ -17,46 +17,57 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - -#include <svl/whiter.hxx> #include <svl/itemset.hxx> +#include <svl/whiter.hxx> -SfxWhichIter::SfxWhichIter( const SfxItemSet& rSet ): - pStart(rSet.GetRanges()), - pRanges(pStart.begin()), - nOffset(0) +SfxWhichIter::SfxWhichIter(const SfxItemSet& rSet) + : m_rItemSet(rSet) + , m_pCurrentWhichPair(rSet.m_pWhichRanges.begin()) + , m_nOffsetFromStartOfCurrentWhichPair(0) + , m_nItemsOffset(0) { } sal_uInt16 SfxWhichIter::GetCurWhich() const { - if ( pRanges >= (pStart.begin() + pStart.size()) ) + const WhichRangesContainer& rWhichRanges = m_rItemSet.m_pWhichRanges; + if (m_pCurrentWhichPair >= (rWhichRanges.begin() + rWhichRanges.size())) return 0; - return pRanges->first + nOffset; + return m_pCurrentWhichPair->first + m_nOffsetFromStartOfCurrentWhichPair; } sal_uInt16 SfxWhichIter::NextWhich() { - if ( pRanges >= (pStart.begin() + pStart.size()) ) + const WhichRangesContainer& rWhichRanges = m_rItemSet.m_pWhichRanges; + if (m_pCurrentWhichPair >= (rWhichRanges.begin() + rWhichRanges.size())) return 0; - const sal_uInt16 nLastWhich = pRanges->first + nOffset; - ++nOffset; - if (pRanges->second == nLastWhich) + const sal_uInt16 nLastWhich = m_pCurrentWhichPair->first + m_nOffsetFromStartOfCurrentWhichPair; + ++m_nOffsetFromStartOfCurrentWhichPair; + if (m_pCurrentWhichPair->second == nLastWhich) { - ++pRanges; - nOffset = 0; + m_nItemsOffset += m_pCurrentWhichPair->second - m_pCurrentWhichPair->first + 1; + ++m_pCurrentWhichPair; + m_nOffsetFromStartOfCurrentWhichPair = 0; } - if ( pRanges >= (pStart.begin() + pStart.size()) ) + if (m_pCurrentWhichPair >= (rWhichRanges.begin() + rWhichRanges.size())) return 0; - return pRanges->first + nOffset; + return m_pCurrentWhichPair->first + m_nOffsetFromStartOfCurrentWhichPair; } sal_uInt16 SfxWhichIter::FirstWhich() { - pRanges = pStart.begin(); - nOffset = 0; - return pRanges->first; + m_pCurrentWhichPair = m_rItemSet.m_pWhichRanges.begin(); + m_nOffsetFromStartOfCurrentWhichPair = 0; + m_nItemsOffset = 0; + return m_pCurrentWhichPair->first; +} + +SfxItemState SfxWhichIter::GetItemState(bool bSrchInParent, const SfxPoolItem** ppItem) const +{ + sal_uInt16 nWhich = m_pCurrentWhichPair->first + m_nOffsetFromStartOfCurrentWhichPair; + sal_uInt16 nItemsOffsetHint = m_nItemsOffset + m_nOffsetFromStartOfCurrentWhichPair; + return m_rItemSet.GetItemStateImpl(nWhich, bSrchInParent, ppItem, nItemsOffsetHint); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |