summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-05-20 16:13:32 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-05-20 20:19:29 -0400
commit266e71c7b89234b9e8722c24dfc9ee7d4ccbd74f (patch)
tree3584ea7b927bbe88a99b81f3da5a8ef1ba2fa2d6 /sc
parent02304b8fc917a8af4230ddf3e26a45000550768a (diff)
Add performance test for repeat-pasting cell to a large cell range.
Change-Id: I98dcdb1e0a72f2c3ad6f33c7b6b7d4a4bcf89096
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/column.hxx1
-rw-r--r--sc/inc/document.hxx5
-rw-r--r--sc/inc/table.hxx1
-rw-r--r--sc/qa/unit/ucalc.cxx80
-rw-r--r--sc/source/core/data/column2.cxx12
-rw-r--r--sc/source/core/data/document.cxx9
-rw-r--r--sc/source/core/data/table1.cxx8
7 files changed, 116 insertions, 0 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index d1492eb0194f..dfc46b0acf9d 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -472,6 +472,7 @@ public:
SvtBroadcaster* GetBroadcaster( SCROW nRow );
const SvtBroadcaster* GetBroadcaster( SCROW nRow ) const;
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
+ bool HasBroadcaster() const;
private:
void UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index ff525a6fb81a..f5d34144e8ab 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1972,6 +1972,11 @@ public:
const SvtBroadcaster* GetBroadcaster( const ScAddress& rPos ) const;
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, const ScAddress& rTopPos, SCROW nLength );
+ /**
+ * See if specified column has any broadcaster at all.
+ */
+ bool HasBroadcaster( SCTAB nTab, SCCOL nCol ) const;
+
private: // CLOOK-Impl-methods
/**
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 6038311682aa..b62fa1e8cf56 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -851,6 +851,7 @@ public:
SvtBroadcaster* GetBroadcaster( SCCOL nCol, SCROW nRow );
const SvtBroadcaster* GetBroadcaster( SCCOL nCol, SCROW nRow ) const;
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 );
+ bool HasBroadcaster( SCCOL nCol ) const;
/** Replace behaves differently to the Search; adjust the rCol and rRow accordingly.
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 07fa33fe44a0..5ebf6b6ffc2f 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -511,6 +511,86 @@ void Test::testPerf()
}
}
+ clearRange(m_pDoc, ScRange(0,0,0,1,MAXROW,0)); // Clear columns A:B.
+ CPPUNIT_ASSERT_MESSAGE("Column A shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,0));
+ CPPUNIT_ASSERT_MESSAGE("Column B shouldn't have any broadcasters.", !m_pDoc->HasBroadcaster(0,1));
+
+ {
+ ScAddress aPos(0,0,0);
+ m_pDoc->SetString(aPos, "test");
+ ScMarkData aMark;
+ aMark.SelectOneTable(0);
+
+ // Copy cell A1 to clipboard.
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ ScClipParam aParam(aPos, false);
+ m_pDoc->CopyToClip(aParam, &aClipDoc, &aMark);
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), aClipDoc.GetString(aPos));
+
+ ScDocument* pUndoDoc = new ScDocument(SCDOCMODE_UNDO);
+ pUndoDoc->InitUndo(m_pDoc, 0, 0);
+ m_pDoc->CopyToDocument(ScRange(aPos), IDF_CONTENTS, false, pUndoDoc, &aMark);
+
+ // Paste it to A2:A100000, and measure its duration.
+ ScRange aPasteRange(0,1,0,0,99999,0);
+ aMark.SetMarkArea(aPasteRange);
+
+ osl_getSystemTime(&aTimeBefore);
+ m_pDoc->CopyFromClip(aPasteRange, aMark, IDF_CONTENTS, pUndoDoc, &aClipDoc);
+ osl_getSystemTime(&aTimeAfter);
+ diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Pasting a single cell to A2:A100000 took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ ScDocument* pRedoDoc = new ScDocument(SCDOCMODE_UNDO);
+ pRedoDoc->InitUndo(m_pDoc, 0, 0);
+ m_pDoc->CopyToDocument(aPasteRange, IDF_CONTENTS, false, pRedoDoc, &aMark);
+
+ // Create an undo object for this.
+ ScRefUndoData* pRefUndoData = new ScRefUndoData(m_pDoc);
+ ScUndoPaste aUndo(&(*m_xDocShRef), aPasteRange, aMark, pUndoDoc, pRedoDoc, IDF_CONTENTS, pRefUndoData);
+
+ // Make sure it did what it's supposed to do.
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
+
+ osl_getSystemTime(&aTimeBefore);
+ aUndo.Undo();
+ osl_getSystemTime(&aTimeAfter);
+ diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Undoing a pasting of a cell to A2:A100000 took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ // Make sure it's really undone.
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, m_pDoc->GetCellType(aPos));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(aPasteRange.aEnd));
+
+ // Now redo.
+ osl_getSystemTime(&aTimeBefore);
+ aUndo.Redo();
+ osl_getSystemTime(&aTimeAfter);
+ diff = getTimeDiff(aTimeAfter, aTimeBefore);
+ if (diff >= 1.0)
+ {
+ std::ostringstream os;
+ os << "Redoing a pasting of a cell to A2:A100000 took " << diff << " seconds. It should be instant.";
+ CPPUNIT_FAIL(os.str().c_str());
+ }
+
+ // Make sure it's really redone.
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aStart));
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), m_pDoc->GetString(aPasteRange.aEnd));
+ }
+
m_pDoc->DeleteTab(0);
}
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 375752c5c085..fbd0c0a26eb0 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1611,6 +1611,18 @@ void ScColumn::DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRo
maBroadcasters.set_empty(rBlockPos.miBroadcasterPos, nRow1, nRow2);
}
+bool ScColumn::HasBroadcaster() const
+{
+ sc::BroadcasterStoreType::const_iterator it = maBroadcasters.begin(), itEnd = maBroadcasters.end();
+ for (; it != itEnd; ++it)
+ {
+ if (it->type == sc::element_type_broadcaster)
+ // Having a broadcaster block automatically means there is at least one broadcaster.
+ return true;
+ }
+ return false;
+}
+
sal_uInt16 ScColumn::GetTextWidth(SCROW nRow) const
{
return maCellTextAttrs.get<sc::CellTextAttr>(nRow).mnTextWidth;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 901476e70a6d..34ae049efc3e 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2257,6 +2257,15 @@ void ScDocument::DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, const S
pTab->DeleteBroadcasters(rBlockPos, rTopPos.Col(), rTopPos.Row(), rTopPos.Row()+nLength-1);
}
+bool ScDocument::HasBroadcaster( SCTAB nTab, SCCOL nCol ) const
+{
+ const ScTable* pTab = FetchTable(nTab);
+ if (!pTab)
+ return false;
+
+ return pTab->HasBroadcaster(nCol);
+}
+
bool ScDocument::TableExists( SCTAB nTab ) const
{
return ValidTab(nTab) && static_cast<size_t>(nTab) < maTabs.size() && maTabs[nTab];
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 9c380c812754..c0e2c3f94e82 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2186,6 +2186,14 @@ void ScTable::DeleteBroadcasters(
aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
}
+bool ScTable::HasBroadcaster( SCCOL nCol ) const
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ return aCol[nCol].HasBroadcaster();
+}
+
const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
{
if (!ValidColRow(nCol, nRow))