sc/qa/unit/ucalc_sort.cxx         |   10 +++++-----
 sc/source/core/data/queryiter.cxx |   23 +++++++++++++----------
 2 files changed, 18 insertions(+), 15 deletions(-)

New commits:
commit 6a5464b800aa0b0ce35d602fd008b555d96a94af
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Fri May 6 09:59:01 2022 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Tue May 10 16:24:13 2022 +0200

    make query iterator's BinarySearch() find the last matching item
    
    If the code found a matching value, it didn't bother finding
    the last one in the range if there were several adjacent ones.
    
    Change-Id: Ie1f4c7bd3dcbd2aaf653f5b74e159902de4cf93d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134098
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/qa/unit/ucalc_sort.cxx b/sc/qa/unit/ucalc_sort.cxx
index ca4b9c319e80..698cbb1bde97 100644
--- a/sc/qa/unit/ucalc_sort.cxx
+++ b/sc/qa/unit/ucalc_sort.cxx
@@ -2100,7 +2100,7 @@ void TestSort::testQueryBinarySearch()
         ScQueryParam param = makeSearchParam( range, ascendingCol, 
SC_LESS_EQUAL, 5 );
         TestQueryIterator it( *m_pDoc, m_pDoc->GetNonThreadedContext(), 0, 
param, false );
         CPPUNIT_ASSERT(it.BinarySearch());
-        // CPPUNIT_ASSERT_EQUAL(SCROW(8), it.GetRow());
+        CPPUNIT_ASSERT_EQUAL(SCROW(8), it.GetRow());
     }
 
     {
@@ -2112,7 +2112,7 @@ void TestSort::testQueryBinarySearch()
         ScQueryParam param = makeSearchParam( range, descendingCol, 
SC_GREATER_EQUAL, 5 );
         TestQueryIterator it( *m_pDoc, m_pDoc->GetNonThreadedContext(), 0, 
param, false );
         CPPUNIT_ASSERT(it.BinarySearch());
-        // CPPUNIT_ASSERT_EQUAL(SCROW(6), it.GetRow());
+        CPPUNIT_ASSERT_EQUAL(SCROW(6), it.GetRow());
     }
 
     {
@@ -2124,7 +2124,7 @@ void TestSort::testQueryBinarySearch()
         ScQueryParam param = makeSearchParam( range, ascendingCol, 
SC_LESS_EQUAL, 6 );
         TestQueryIterator it( *m_pDoc, m_pDoc->GetNonThreadedContext(), 0, 
param, false );
         CPPUNIT_ASSERT(it.BinarySearch());
-        // CPPUNIT_ASSERT_EQUAL(SCROW(8), it.GetRow());
+        CPPUNIT_ASSERT_EQUAL(SCROW(8), it.GetRow());
     }
 
     {
@@ -2136,7 +2136,7 @@ void TestSort::testQueryBinarySearch()
         ScQueryParam param = makeSearchParam( range, descendingCol, 
SC_GREATER_EQUAL, 6 );
         TestQueryIterator it( *m_pDoc, m_pDoc->GetNonThreadedContext(), 0, 
param, false );
         CPPUNIT_ASSERT(it.BinarySearch());
-        // CPPUNIT_ASSERT_EQUAL(SCROW(1), it.GetRow());
+        CPPUNIT_ASSERT_EQUAL(SCROW(1), it.GetRow());
     }
 
     {
@@ -2172,7 +2172,7 @@ void TestSort::testQueryBinarySearch()
         ScQueryParam param = makeSearchParam( range, ascendingCol, 
SC_LESS_EQUAL, 10 );
         TestQueryIterator it( *m_pDoc, m_pDoc->GetNonThreadedContext(), 0, 
param, false );
         CPPUNIT_ASSERT(it.BinarySearch());
-        // CPPUNIT_ASSERT_EQUAL(SCROW(10), it.GetRow());
+        CPPUNIT_ASSERT_EQUAL(SCROW(10), it.GetRow());
     }
 
     {
diff --git a/sc/source/core/data/queryiter.cxx 
b/sc/source/core/data/queryiter.cxx
index ec88e35ff6a5..60d62ad2da60 100644
--- a/sc/source/core/data/queryiter.cxx
+++ b/sc/source/core/data/queryiter.cxx
@@ -394,7 +394,7 @@ bool ScQueryCellIteratorBase< accessType, queryType 
>::BinarySearch()
     }
 
     sal_Int32 nRes = 0;
-    bool bFound = false;
+    std::optional<size_t> found;
     bool bDone = false;
     while (nLo <= nHi && !bDone)
     {
@@ -426,12 +426,12 @@ bool ScQueryCellIteratorBase< accessType, queryType 
>::BinarySearch()
                 nRes = -1;
                 if (bLessEqual)
                 {
-                    if (fLastInRangeValue < nCellVal)
+                    if (fLastInRangeValue <= nCellVal)
                     {
                         fLastInRangeValue = nCellVal;
                         nLastInRange = i;
                     }
-                    else if (fLastInRangeValue > nCellVal)
+                    else if (fLastInRangeValue >= nCellVal)
                     {
                         // not strictly sorted, continue with GetThis()
                         nLastInRange = nFirstLastInRange;
@@ -445,12 +445,12 @@ bool ScQueryCellIteratorBase< accessType, queryType 
>::BinarySearch()
                 nRes = 1;
                 if (!bLessEqual)
                 {
-                    if (fLastInRangeValue > nCellVal)
+                    if (fLastInRangeValue >= nCellVal)
                     {
                         fLastInRangeValue = nCellVal;
                         nLastInRange = i;
                     }
-                    else if (fLastInRangeValue < nCellVal)
+                    else if (fLastInRangeValue <= nCellVal)
                     {
                         // not strictly sorted, continue with GetThis()
                         nLastInRange = nFirstLastInRange;
@@ -469,7 +469,7 @@ bool ScQueryCellIteratorBase< accessType, queryType 
>::BinarySearch()
             {
                 sal_Int32 nTmp = rCollator.compareString( aLastInRangeString,
                         aCellStr);
-                if (nTmp < 0)
+                if (nTmp <= 0)
                 {
                     aLastInRangeString = aCellStr;
                     nLastInRange = i;
@@ -485,7 +485,7 @@ bool ScQueryCellIteratorBase< accessType, queryType 
>::BinarySearch()
             {
                 sal_Int32 nTmp = rCollator.compareString( aLastInRangeString,
                         aCellStr);
-                if (nTmp > 0)
+                if (nTmp >= 0)
                 {
                     aLastInRangeString = aCellStr;
                     nLastInRange = i;
@@ -536,12 +536,15 @@ bool ScQueryCellIteratorBase< accessType, queryType 
>::BinarySearch()
         }
         else
         {
-            nLo = i;
-            bDone = bFound = true;
+            found = i;
+            // But keep searching to find the last matching one.
+            nLo = nMid + 1;
         }
     }
 
-    if (!bFound)
+    if (found)
+        nLo = *found;
+    else
     {
         // If all hits didn't result in a moving limit there's something
         // strange, e.g. data range not properly sorted, or only identical

Reply via email to