summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2016-07-16 20:01:48 -0400
committerKohei Yoshida <libreoffice@kohei.us>2016-07-17 13:00:36 +0000
commite57a5905fb2975307af654710430d0a876dbd061 (patch)
tree364527c7b09f9704e6c6ece7ca473c9e2030177f
parent0473f6fc0445272b1e9d01ca9166d4fae58a5a56 (diff)
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@kohei.us> Tested-by: Kohei Yoshida <libreoffice@kohei.us>
-rw-r--r--sc/inc/column.hxx6
-rw-r--r--sc/inc/mtvelements.hxx14
-rw-r--r--sc/source/core/data/column.cxx7
-rw-r--r--sc/source/core/data/column4.cxx17
-rw-r--r--sc/source/core/data/mtvelements.cxx35
5 files changed, 76 insertions, 3 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 611496868d1c..4c2ebca317db 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 18edafc40e70..ae3a91ad5b3f 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 5766c72efa4f..00664c63bf43 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 6e8e4daa753c..f46c6ae2d180 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 d3847ed17289..cf436ba4cec6 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)