[Libreoffice-commits] core.git: sc/inc sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Sun Jul 17 13:02:10 UTC 2016


 sc/inc/column.hxx                   |    6 ++++++
 sc/inc/mtvelements.hxx              |   14 +++++++++++++-
 sc/source/core/data/column.cxx      |    7 +++++--
 sc/source/core/data/column4.cxx     |   17 +++++++++++++++++
 sc/source/core/data/mtvelements.cxx |   35 +++++++++++++++++++++++++++++++++++
 5 files changed, 76 insertions(+), 3 deletions(-)

New commits:
commit e57a5905fb2975307af654710430d0a876dbd061
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sat Jul 16 20:01:48 2016 -0400

    Use mdds' event callback to count formula blocks in each column.
    
    And use it to speed up certain formula related operations.
    
    Change-Id: I43b1d860d6b665556624ba7bc716826799919015
    Reviewed-on: https://gerrit.libreoffice.org/27261
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    Tested-by: Kohei Yoshida <libreoffice at kohei.us>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 6114968..4c2ebca 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -130,6 +130,8 @@ class ScColumn
     // Broadcasters for formula cells.
     sc::BroadcasterStoreType maBroadcasters;
 
+    sc::CellStoreEvent maCellsEvent;
+
     // Cell values.
     sc::CellStoreType maCells;
 
@@ -140,6 +142,8 @@ class ScColumn
     ScDocument*           pDocument;
     bool mbDirtyGroups;     /// formula groups are dirty.
 
+    size_t mnBlkCountFormula;
+
 friend class ScDocument;                    // for FillInfo
 friend class ScTable;
 friend class ScValueIterator;
@@ -158,6 +162,7 @@ friend class sc::ColumnSpanSet;
 friend class sc::EditTextIterator;
 friend class sc::CellValues;
 friend class sc::TableValues;
+friend class sc::CellStoreEvent;
 
     ScColumn(const ScColumn&) = delete;
     ScColumn& operator= (const ScColumn&) = delete;
@@ -339,6 +344,7 @@ public:
 
     bool SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells );
 
+    bool HasFormulaCell() const;
     bool HasFormulaCell( SCROW nRow1, SCROW nRow2 ) const;
 
     void CloneFormulaCell(
diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index 18edafc..ae3a91a 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -35,6 +35,7 @@
 #include <unordered_map>
 
 class ScDocument;
+class ScColumn;
 struct ScRefCellValue;
 
 namespace sc {
@@ -86,6 +87,17 @@ MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(SharedString, sc::element_type_string, SharedS
 
 namespace sc {
 
+class CellStoreEvent
+{
+    ScColumn* mpCol;
+public:
+    CellStoreEvent();
+    CellStoreEvent(ScColumn* pCol);
+
+    void element_block_acquired(const mdds::mtv::base_element_block* block);
+    void element_block_released(const mdds::mtv::base_element_block* block);
+};
+
 /// Cell note container
 typedef mdds::mtv::custom_block_func1<sc::cellnote_block> CNoteFunc;
 typedef mdds::multi_type_vector<CNoteFunc> CellNoteStoreType;
@@ -100,7 +112,7 @@ typedef mdds::multi_type_vector<CTAttrFunc> CellTextAttrStoreType;
 
 /// Cell container
 typedef mdds::mtv::custom_block_func3<sc::string_block, sc::edittext_block, sc::formula_block> CellFunc;
-typedef mdds::multi_type_vector<CellFunc> CellStoreType;
+typedef mdds::multi_type_vector<CellFunc, CellStoreEvent> CellStoreType;
 
 /**
  * Store position data for column array storage.
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 5766c72..00664c6 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -84,13 +84,16 @@ ScColumn::ScColumn() :
     maCellTextAttrs(MAXROWCOUNT),
     maCellNotes(MAXROWCOUNT),
     maBroadcasters(MAXROWCOUNT),
-    maCells(MAXROWCOUNT),
+    maCellsEvent(this),
+    maCells(maCellsEvent),
     nCol( 0 ),
     nTab( 0 ),
     pAttrArray( nullptr ),
     pDocument( nullptr ),
-    mbDirtyGroups(true)
+    mbDirtyGroups(true),
+    mnBlkCountFormula(0)
 {
+    maCells.resize(MAXROWCOUNT);
 }
 
 ScColumn::~ScColumn()
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 6e8e4da..f46c6ae 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1142,6 +1142,11 @@ void ScColumn::CollectFormulaCells( std::vector<ScFormulaCell*>& rCells, SCROW n
     sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aFunc);
 }
 
+bool ScColumn::HasFormulaCell() const
+{
+    return mnBlkCountFormula != 0;
+}
+
 namespace {
 
 struct FindAnyFormula
@@ -1156,9 +1161,15 @@ struct FindAnyFormula
 
 bool ScColumn::HasFormulaCell( SCROW nRow1, SCROW nRow2 ) const
 {
+    if (!mnBlkCountFormula)
+        return false;
+
     if (nRow2 < nRow1 || !ValidRow(nRow1) || !ValidRow(nRow2))
         return false;
 
+    if (nRow1 == 0 && nRow2 == MAXROW)
+        return HasFormulaCell();
+
     FindAnyFormula aFunc;
     std::pair<sc::CellStoreType::const_iterator, size_t> aRet =
         sc::FindFormula(maCells, nRow1, nRow2, aFunc);
@@ -1344,6 +1355,9 @@ void ScColumn::StartListeningFormulaCells(
     sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt,
     SCROW nRow1, SCROW nRow2 )
 {
+    if (!HasFormulaCell())
+        return;
+
     StartListeningFormulaCellsHandler aFunc(rStartCxt, rEndCxt);
     sc::ProcessBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
 }
@@ -1352,6 +1366,9 @@ void ScColumn::EndListeningFormulaCells(
     sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2,
     SCROW* pStartRow, SCROW* pEndRow )
 {
+    if (!HasFormulaCell())
+        return;
+
     EndListeningFormulaCellsHandler aFunc(rCxt);
     sc::ProcessBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
 
diff --git a/sc/source/core/data/mtvelements.cxx b/sc/source/core/data/mtvelements.cxx
index d3847ed..cf436ba 100644
--- a/sc/source/core/data/mtvelements.cxx
+++ b/sc/source/core/data/mtvelements.cxx
@@ -11,9 +11,44 @@
 #include "globalnames.hxx"
 #include "document.hxx"
 #include "cellvalue.hxx"
+#include "column.hxx"
 
 namespace sc {
 
+CellStoreEvent::CellStoreEvent() : mpCol(nullptr) {}
+
+CellStoreEvent::CellStoreEvent(ScColumn* pCol) : mpCol(pCol) {}
+
+void CellStoreEvent::element_block_acquired(const mdds::mtv::base_element_block* block)
+{
+    if (!mpCol)
+        return;
+
+    switch (mdds::mtv::get_block_type(*block))
+    {
+        case sc::element_type_formula:
+            ++mpCol->mnBlkCountFormula;
+            break;
+        default:
+            ;
+    }
+}
+
+void CellStoreEvent::element_block_released(const mdds::mtv::base_element_block* block)
+{
+    if (!mpCol)
+        return;
+
+    switch (mdds::mtv::get_block_type(*block))
+    {
+        case sc::element_type_formula:
+            --mpCol->mnBlkCountFormula;
+            break;
+        default:
+            ;
+    }
+}
+
 ColumnBlockPositionSet::ColumnBlockPositionSet(ScDocument& rDoc) : mrDoc(rDoc) {}
 
 ColumnBlockPosition* ColumnBlockPositionSet::getBlockPosition(SCTAB nTab, SCCOL nCol)


More information about the Libreoffice-commits mailing list