sc/inc/column.hxx                   |    3 ++-
 sc/inc/mtvelements.hxx              |    5 +++--
 sc/source/core/data/column.cxx      |    6 +++++-
 sc/source/core/data/column2.cxx     |    4 +---
 sc/source/core/data/column4.cxx     |   12 ++++++++++++
 sc/source/core/data/mtvelements.cxx |    6 ++++++
 6 files changed, 29 insertions(+), 7 deletions(-)

New commits:
commit 25ffb54c6d8a5b52dca6b782282962766e7791de
Author:     Kohei Yoshida <ko...@libreoffice.org>
AuthorDate: Mon Feb 26 19:50:19 2024 -0500
Commit:     Kohei Yoshida <ko...@libreoffice.org>
CommitDate: Tue Feb 27 04:02:57 2024 +0100

    Make ScColumn::HasCellNotes() less expensive
    
    It's essentially the same idea as checking if the column has formula cells; 
by keeping track of the block creation and deletion events to
    count the number of cell notes block instances at any given moment, and
    use that information to see if the column has any cell notes.
    
    Change-Id: I95c5186bf1f21f23f85fa10ff3c2135388949c72
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163996
    Tested-by: Kohei Yoshida <ko...@libreoffice.org>
    Reviewed-by: Kohei Yoshida <ko...@libreoffice.org>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 0e07ed8142b0..7b07f310b23e 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -206,7 +206,8 @@ class ScColumn : protected ScColumnData
     // Sparklines
     sc::SparklineStoreType maSparklines;
 
-    size_t mnBlkCountFormula;
+    std::size_t mnBlkCountFormula;
+    std::size_t mnBlkCountCellNotes;
 
     SCCOL           nCol;
     SCTAB           nTab;
diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index 156346a945ba..9a7b525fb82a 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -114,8 +114,9 @@ struct SparklineTraits : public mdds::mtv::default_traits
     using block_funcs = mdds::mtv::element_block_funcs<sc::sparkline_block>;
 };
 
-struct CellNodeTraits : public mdds::mtv::default_traits
+struct CellNoteTraits : public mdds::mtv::default_traits
 {
+    using event_func = CellStoreEvent;
     using block_funcs = mdds::mtv::element_block_funcs<sc::cellnote_block>;
 };
 
@@ -140,7 +141,7 @@ struct CellStoreTraits : public mdds::mtv::default_traits
 typedef mdds::mtv::soa::multi_type_vector<SparklineTraits> SparklineStoreType;
 
 /// Cell note container
-typedef mdds::mtv::soa::multi_type_vector<CellNodeTraits> CellNoteStoreType;
+typedef mdds::mtv::soa::multi_type_vector<CellNoteTraits> CellNoteStoreType;
 
 /// Broadcaster storage container
 typedef mdds::mtv::soa::multi_type_vector<BroadcasterTraits> 
BroadcasterStoreType;
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 4df322def537..22d8cec28bc3 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -82,15 +82,17 @@ ScNeededSizeOptions::ScNeededSizeOptions() :
 
 ScColumn::ScColumn(ScSheetLimits const & rSheetLimits) :
     maCellTextAttrs(rSheetLimits.GetMaxRowCount()),
-    maCellNotes(rSheetLimits.GetMaxRowCount()),
+    maCellNotes(sc::CellStoreEvent(this)),
     maBroadcasters(rSheetLimits.GetMaxRowCount()),
     maCells(sc::CellStoreEvent(this)),
     maSparklines(rSheetLimits.GetMaxRowCount()),
     mnBlkCountFormula(0),
+    mnBlkCountCellNotes(0),
     nCol( 0 ),
     nTab( 0 ),
     mbEmptyBroadcastersPending( false )
 {
+    maCellNotes.resize(rSheetLimits.GetMaxRowCount());
     maCells.resize(rSheetLimits.GetMaxRowCount());
 }
 
@@ -1829,7 +1831,9 @@ void ScColumn::SwapCol(ScColumn& rCol)
 
     // Swap all CellStoreEvent mdds event_func related.
     maCells.event_handler().swap(rCol.maCells.event_handler());
+    maCellNotes.event_handler().swap(rCol.maCellNotes.event_handler());
     std::swap( mnBlkCountFormula, rCol.mnBlkCountFormula);
+    std::swap(mnBlkCountCellNotes, rCol.mnBlkCountCellNotes);
 
     // notes update caption
     UpdateNoteCaptions(0, GetDoc().MaxRow());
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 20e365acb06c..b9dcbf68bef2 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2275,9 +2275,7 @@ void ScColumn::DeleteCellNotes( sc::ColumnBlockPosition& 
rBlockPos, SCROW nRow1,
 
 bool ScColumn::HasCellNotes() const
 {
-    if (maCellNotes.block_size() == 1 && maCellNotes.begin()->type == 
sc::element_type_empty)
-        return false; // all elements are empty
-    return true; // otherwise some must be notes
+    return mnBlkCountCellNotes != 0;
 }
 
 SCROW ScColumn::GetCellNotesMaxRow() const
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 2f9c46deb838..bd9bba3df1f4 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -2233,6 +2233,18 @@ void ScColumn::CheckIntegrity() const
             << mnBlkCountFormula << ")";
         throw std::runtime_error(os.str());
     }
+
+    nCount = std::count_if(maCellNotes.cbegin(), maCellNotes.cend(),
+        [](const auto& blk) { return blk.type == sc::element_type_cellnote; }
+    );
+
+    if (mnBlkCountCellNotes != nCount)
+    {
+        std::ostringstream os;
+        os << "incorrect cached cell note block count (expected=" << nCount << 
"; actual="
+            << mnBlkCountCellNotes << ")";
+        throw std::runtime_error(os.str());
+    }
 }
 
 void ScColumn::CollectBroadcasterState(sc::BroadcasterState& rState) const
diff --git a/sc/source/core/data/mtvelements.cxx 
b/sc/source/core/data/mtvelements.cxx
index 9bc28056bd79..9f5399701d31 100644
--- a/sc/source/core/data/mtvelements.cxx
+++ b/sc/source/core/data/mtvelements.cxx
@@ -31,6 +31,9 @@ void CellStoreEvent::element_block_acquired(const 
mdds::mtv::base_element_block*
         case sc::element_type_formula:
             ++mpCol->mnBlkCountFormula;
             break;
+        case sc::element_type_cellnote:
+            ++mpCol->mnBlkCountCellNotes;
+            break;
         default:
             ;
     }
@@ -46,6 +49,9 @@ void CellStoreEvent::element_block_released(const 
mdds::mtv::base_element_block*
         case sc::element_type_formula:
             --mpCol->mnBlkCountFormula;
             break;
+        case sc::element_type_cellnote:
+            --mpCol->mnBlkCountCellNotes;
+            break;
         default:
             ;
     }

Reply via email to