sc/inc/queryiter.hxx | 8 ++++---- sc/source/core/data/queryiter.cxx | 27 +++++++++++++++++---------- sc/source/core/inc/interpre.hxx | 6 +++--- sc/source/core/tool/interpr1.cxx | 35 ++++++++++++++++++----------------- 4 files changed, 42 insertions(+), 34 deletions(-)
New commits: commit 88ba9fab08514b96f458bb8c0ace175b2790638e Author: Winfried Donkers <[email protected]> AuthorDate: Sun Feb 11 16:18:44 2024 +0100 Commit: Balazs Varga <[email protected]> CommitDate: Fri Feb 16 11:01:17 2024 +0100 Prepare search code for other functions than MATCH and XLOOKUP. Purpose is to use one set of code for all similar lookup functions, as they now each have their own code, which is largely identical. Next steps will be to make the code used by XLOOKUP and MATCH work with each similar lookup function. This patch just changes the interface to accomodate other functions. Change-Id: I6950aa69404f3eb8acbf2d55e247058f3e798814 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163230 Tested-by: Jenkins Reviewed-by: Balazs Varga <[email protected]> diff --git a/sc/inc/queryiter.hxx b/sc/inc/queryiter.hxx index 32fd1cb83898..f494b83d74a5 100644 --- a/sc/inc/queryiter.hxx +++ b/sc/inc/queryiter.hxx @@ -183,7 +183,7 @@ protected: sal_uInt8 nSortedBinarySearch; bool bAdvanceQuery; bool bIgnoreMismatchOnLeadingStrings; - bool bXLookUp; + sal_uInt16 nSearchOpCode; SCCOL nBestFitCol; SCROW nBestFitRow; @@ -276,8 +276,8 @@ public: nSearchbAscd : (nSearchMode == -2 ? nSearchbDesc : nBinarySearchDisabled)); } - void SetXlookupMode( bool bVal ) - { bXLookUp = bVal; } + void SetLookupMode( sal_uInt16 nVal ) + { nSearchOpCode = nVal; } }; @@ -325,7 +325,7 @@ class ScQueryCellIterator using Base::getThisResult; using Base::nBestFitCol; using Base::nBestFitRow; - using Base::bXLookUp; + using Base::nSearchOpCode; bool GetThis(); diff --git a/sc/source/core/data/queryiter.cxx b/sc/source/core/data/queryiter.cxx index 56d4081e7255..8abaa2b93fdd 100644 --- a/sc/source/core/data/queryiter.cxx +++ b/sc/source/core/data/queryiter.cxx @@ -67,7 +67,7 @@ ScQueryCellIteratorBase< accessType, queryType >::ScQueryCellIteratorBase(ScDocu , nSortedBinarySearch( nBinarySearchDisabled ) , bAdvanceQuery( false ) , bIgnoreMismatchOnLeadingStrings( false ) - , bXLookUp( false ) + , nSearchOpCode( SC_OPCODE_NONE ) , nBestFitCol(SCCOL_MAX) , nBestFitRow(SCROW_MAX) { @@ -207,7 +207,8 @@ void ScQueryCellIteratorBase< accessType, queryType >::PerformQuery() return; // XLookUp: Forward/asc/backward/desc search for best fit value, except if we have an exact match - if (bXLookUp && (rEntry.eOp == SC_LESS_EQUAL || rEntry.eOp == SC_GREATER_EQUAL) && + if (nSearchOpCode == SC_OPCODE_X_LOOKUP && + (rEntry.eOp == SC_LESS_EQUAL || rEntry.eOp == SC_GREATER_EQUAL) && (nBestFitCol != nCol || nBestFitRow != nRow)) { bool bNumSearch = rItem.meType == ScQueryEntry::ByValue && aCell.hasNumeric(); @@ -315,7 +316,7 @@ void ScQueryCellIteratorBase< accessType, queryType >::InitPos() // is the one after it. lastRow = nRow; // BinarySearch() looks for the first match for XLOOKUP - if (!bXLookUp) + if (nSearchOpCode != SC_OPCODE_X_LOOKUP) { ScQueryOp saveOp = op; op = SC_LESS; @@ -341,7 +342,7 @@ void ScQueryCellIteratorBase< accessType, queryType >::InitPos() if( BinarySearch( nCol )) lastRow = nRow; } - AccessBase::InitPosFinish(beforeRow, lastRow, bXLookUp); + AccessBase::InitPosFinish(beforeRow, lastRow, (nSearchOpCode == SC_OPCODE_X_LOOKUP)); } } @@ -545,7 +546,9 @@ bool ScQueryCellIteratorBase< accessType, queryType >::BinarySearch( SCCOL col, { if (fLastInRangeValue <= nCellVal) { - if (bXLookUp && nSortedBinarySearch != nSearchbDesc && fLastInRangeValue == nCellVal && aIndexer.getLowIndex() != i) + if (nSearchOpCode == SC_OPCODE_X_LOOKUP && + nSortedBinarySearch != nSearchbDesc && + fLastInRangeValue == nCellVal && aIndexer.getLowIndex() != i) bDone = true; else { @@ -593,7 +596,9 @@ bool ScQueryCellIteratorBase< accessType, queryType >::BinarySearch( SCCOL col, aCellStr); if (nTmp <= 0) { - if (bXLookUp && nSortedBinarySearch != nSearchbDesc && nTmp == 0 && aIndexer.getLowIndex() != i) + if (nSearchOpCode == SC_OPCODE_X_LOOKUP && + nSortedBinarySearch != nSearchbDesc && + nTmp == 0 && aIndexer.getLowIndex() != i) bDone = true; else { @@ -667,7 +672,8 @@ bool ScQueryCellIteratorBase< accessType, queryType >::BinarySearch( SCCOL col, { found = i; nLastInRange = i; - if (bXLookUp && (nSortedBinarySearch == nSearchbAscd && (rEntry.eOp == SC_LESS_EQUAL || rEntry.eOp == SC_EQUAL))) + if (nSearchOpCode == SC_OPCODE_X_LOOKUP && (nSortedBinarySearch == nSearchbAscd && + (rEntry.eOp == SC_LESS_EQUAL || rEntry.eOp == SC_EQUAL))) bDone = true; else // But keep searching to find the last matching one. nLo = nMid + 1; @@ -747,7 +753,7 @@ bool ScQueryCellIterator< accessType >::FindEqualOrSortedLastInRange( SCCOL& nFo nFoundCol = rDoc.MaxCol()+1; nFoundRow = rDoc.MaxRow()+1; - if (bXLookUp && nSortedBinarySearch == nBinarySearchDisabled) + if (nSearchOpCode == SC_OPCODE_X_LOOKUP && nSortedBinarySearch == nBinarySearchDisabled) SetStopOnMismatch( false ); // assume not sorted keys for XLookup else SetStopOnMismatch( true ); // assume sorted keys @@ -762,7 +768,8 @@ bool ScQueryCellIterator< accessType >::FindEqualOrSortedLastInRange( SCCOL& nFo (maParam.GetEntry(0).eOp == SC_LESS_EQUAL || maParam.GetEntry(0).eOp == SC_GREATER_EQUAL); // assume not sorted properly if we are using XLookup with forward or backward search - if (bBinary && bXLookUp && nSortedBinarySearch == nBinarySearchDisabled) + if (bBinary && nSearchOpCode == SC_OPCODE_X_LOOKUP && + nSortedBinarySearch == nBinarySearchDisabled) bBinary = false; bool bFound = false; @@ -855,7 +862,7 @@ bool ScQueryCellIterator< accessType >::FindEqualOrSortedLastInRange( SCCOL& nFo } } } - if ( IsEqualConditionFulfilled() && !bXLookUp ) + if ( IsEqualConditionFulfilled() && nSearchOpCode != SC_OPCODE_X_LOOKUP ) { // Position on last equal entry, except for XLOOKUP, // which looking for the first equal entry diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index ea30b57ae7ea..57c69d6a3d02 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -61,8 +61,8 @@ enum SearchMode{ searchfwd=1, searchrev=-1, searchbasc=2, searchbdesc=-2 }; struct VectorSearchArguments { // struct contains the contents of the function arguments - // Struct owner, ScMatch or ScXLookup - bool isXLookup = false; + // OpCode of struct owner + sal_uInt16 nSearchOpCode = SC_OPCODE_NONE; // match mode (common, enum values are from XLOOKUP) // optional 5th argument to set match mode @@ -541,7 +541,7 @@ private: inline void TreatDoubleError( double& rVal ); // Lookup using ScLookupCache, @returns true if found and result address bool LookupQueryWithCache( ScAddress & o_rResultPos, const ScQueryParam & rParam, - const ScComplexRefData* refData, sal_Int8 nSearchMode, bool bXlookupMode ) const; + const ScComplexRefData* refData, sal_Int8 nSearchMode, sal_Int16 nOpCode ) const; void ScIfJump(); void ScIfError( bool bNAonly ); diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 3d3b967ffaa0..fd7bab714805 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -4920,7 +4920,7 @@ void ScInterpreter::ScMatch() return; VectorSearchArguments vsa; - vsa.isXLookup = false; + vsa.nSearchOpCode = SC_OPCODE_MATCH; // get match mode double fType = ( nParamCount == 3 ? GetDouble() : 1.0 ); @@ -7545,7 +7545,8 @@ void ScInterpreter::CalculateLookup(bool bHLookup) else { ScAddress aResultPos( nCol1, nRow1, nTab1); - bFound = LookupQueryWithCache( aResultPos, aParam, refData, 0, false ); + bFound = LookupQueryWithCache( aResultPos, aParam, refData, 0, + ( bHLookup ? SC_OPCODE_H_LOOKUP : SC_OPCODE_V_LOOKUP ) ); nRow = aResultPos.Row(); nCol = nSpIndex; } @@ -7638,7 +7639,7 @@ void ScInterpreter::ScXLookup() return; VectorSearchArguments vsa; - vsa.isXLookup = true; + vsa.nSearchOpCode = SC_OPCODE_X_LOOKUP; if ( nParamCount == 6 ) { @@ -10663,7 +10664,7 @@ bool ScInterpreter::SearchRangeForValue( VectorSearchArguments& vsa, ScQueryPara rParam.bByRow = true; ScAddress aResultPos( vsa.nCol1, vsa.nRow1, vsa.nTab1 ); const ScComplexRefData* refData = nullptr; - if ( LookupQueryWithCache( aResultPos, rParam, refData, vsa.eSearchMode, vsa.isXLookup ) ) + if ( LookupQueryWithCache( aResultPos, rParam, refData, vsa.eSearchMode, vsa.nSearchOpCode ) ) vsa.nHitIndex = aResultPos.Row() - vsa.nRow1 + 1; } else @@ -10674,7 +10675,7 @@ bool ScInterpreter::SearchRangeForValue( VectorSearchArguments& vsa, ScQueryPara ScQueryCellIteratorDirect aCellIter(mrDoc, mrContext, vsa.nTab1, rParam, false, bReverseSearch); // Advance Entry.nField in Iterator if column changed aCellIter.SetAdvanceQueryParamEntryField(true); - aCellIter.SetXlookupMode(vsa.isXLookup); + aCellIter.SetLookupMode(vsa.nSearchOpCode); // TODO: no binary search for column (horizontal) search (use linear) aCellIter.SetSortedBinarySearchMode(vsa.eSearchMode); if (rEntry.eOp == SC_EQUAL) @@ -10741,7 +10742,7 @@ bool ScInterpreter::SearchVectorForValue( VectorSearchArguments& vsa ) case wildcard : // this mode can only used with XLOOKUP - if ( vsa.isXLookup ) + if ( vsa.nSearchOpCode == SC_OPCODE_X_LOOKUP ) { rEntry.eOp = SC_EQUAL; if ( vsa.isStringSearch ) @@ -10774,7 +10775,7 @@ bool ScInterpreter::SearchVectorForValue( VectorSearchArguments& vsa ) { rItem.meType = ScQueryEntry::ByString; rItem.maString = vsa.sSearchStr; - if ( !vsa.isXLookup ) + if ( vsa.nSearchOpCode == SC_OPCODE_MATCH ) { if ( mrDoc.IsInVBAMode() ) rParam.eSearchType = utl::SearchParam::SearchType::Wildcard; @@ -10805,12 +10806,12 @@ bool ScInterpreter::SearchVectorForValue( VectorSearchArguments& vsa ) // MATCH expects index starting with 1, XLOOKUP expects index starting with 0 if ( vsa.nHitIndex > 0 ) { - vsa.nIndex = ( vsa.isXLookup ? --vsa.nHitIndex : vsa.nHitIndex ); + vsa.nIndex = ( vsa.nSearchOpCode == SC_OPCODE_X_LOOKUP ? --vsa.nHitIndex : vsa.nHitIndex ); return true; } else if ( vsa.nHitIndex == 0 && vsa.nBestFit != SCSIZE_MAX ) { - if ( vsa.isXLookup ) + if ( vsa.nSearchOpCode == SC_OPCODE_X_LOOKUP ) { vsa.nIndex = vsa.nBestFit; if ( !vsa.pMatSrc ) @@ -10832,7 +10833,7 @@ bool ScInterpreter::SearchVectorForValue( VectorSearchArguments& vsa ) static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument& rDoc, ScInterpreterContext& rContext, const ScQueryParam & rParam, const ScQueryEntry & rEntry, const ScFormulaCell* cell, - const ScComplexRefData* refData, sal_Int8 nSearchMode, bool bXlookupMode ) + const ScComplexRefData* refData, sal_Int8 nSearchMode, sal_Int16 nOpCode ) { if (rEntry.eOp != SC_EQUAL) { @@ -10849,7 +10850,7 @@ static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument& rDoc, ScInter // search for the first GreaterOrEqual value if SearchMode is asc ScQueryCellIteratorSortedCache aCellIter(rDoc, rContext, rParam.nTab, rParam, false, false); aCellIter.SetSortedBinarySearchMode(nSearchMode); - aCellIter.SetXlookupMode(bXlookupMode); + aCellIter.SetLookupMode(nOpCode); if (aCellIter.GetFirst()) { o_rResultPos.SetCol(aCellIter.GetCol()); @@ -10864,7 +10865,7 @@ static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument& rDoc, ScInter ScQueryCellIteratorDirect aCellIter(rDoc, rContext, rParam.nTab, rParam, false, bReverse); aCellIter.SetSortedBinarySearchMode(nSearchMode); - aCellIter.SetXlookupMode(bXlookupMode); + aCellIter.SetLookupMode(nOpCode); if (aCellIter.FindEqualOrSortedLastInRange(nCol, nRow)) { o_rResultPos.SetCol(nCol); @@ -10886,7 +10887,7 @@ static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument& rDoc, ScInter { ScQueryCellIteratorSortedCache aCellIter( rDoc, rContext, rParam.nTab, rParam, false, false ); aCellIter.SetSortedBinarySearchMode(nSearchMode); - aCellIter.SetXlookupMode(bXlookupMode); + aCellIter.SetLookupMode(nOpCode); if (aCellIter.GetFirst()) { o_rResultPos.SetCol( aCellIter.GetCol()); @@ -10899,7 +10900,7 @@ static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument& rDoc, ScInter ScQueryCellIteratorDirect aCellIter( rDoc, rContext, rParam.nTab, rParam, false, static_cast<SearchMode>(nSearchMode) == searchrev); aCellIter.SetSortedBinarySearchMode(nSearchMode); - aCellIter.SetXlookupMode(bXlookupMode); + aCellIter.SetLookupMode(nOpCode); if (aCellIter.GetFirst()) { o_rResultPos.SetCol( aCellIter.GetCol()); @@ -10951,7 +10952,7 @@ static SCROW lcl_getPrevRowWithEmptyValueLookup( const ScLookupCache& rCache, bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos, const ScQueryParam & rParam, const ScComplexRefData* refData, - sal_Int8 nSearchMode, bool bXlookupMode ) const + sal_Int8 nSearchMode, sal_Int16 nOpCode ) const { bool bFound = false; const ScQueryEntry& rEntry = rParam.GetEntry(0); @@ -10964,7 +10965,7 @@ bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos, * parameter so it would affect only the lookup range parameter. */ if (!bColumnsMatch || GetVolatileType() != NOT_VOLATILE) bFound = lcl_LookupQuery( o_rResultPos, mrDoc, mrContext, rParam, rEntry, pMyFormulaCell, - refData, nSearchMode, bXlookupMode ); + refData, nSearchMode, nOpCode ); else { ScRange aLookupRange( rParam.nCol1, rParam.nRow1, rParam.nTab, @@ -10996,7 +10997,7 @@ bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos, case ScLookupCache::NOT_CACHED : case ScLookupCache::CRITERIA_DIFFERENT : bFound = lcl_LookupQuery( o_rResultPos, mrDoc, mrContext, rParam, rEntry, - pMyFormulaCell, refData, nSearchMode, bXlookupMode ); + pMyFormulaCell, refData, nSearchMode, nOpCode ); if (eCacheResult == ScLookupCache::NOT_CACHED) rCache.insert( o_rResultPos, aCriteria, aPos, bFound); break;
