[Libreoffice-commits] core.git: sc/inc sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Fri Dec 23 03:38:57 UTC 2016
sc/inc/document.hxx | 2
sc/inc/documentimport.hxx | 6 ++
sc/inc/mtvelements.hxx | 17 +++++++
sc/source/core/data/documentimport.cxx | 69 ++++++++++++++++++++----------
sc/source/core/data/mtvelements.cxx | 59 +++++++++++++++++++++++++
sc/source/filter/oox/workbookfragment.cxx | 2
6 files changed, 133 insertions(+), 22 deletions(-)
New commits:
commit 4252096c68ce01ed8a06bcaf57260dbe46502cd3
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Dec 20 22:32:50 2016 -0500
tdf#97597: Make the document import state more multi-thread friendly.
Change-Id: Iee9ff5e5d3471f7357a1f2eaf75abbef2d90effa
Reviewed-on: https://gerrit.libreoffice.org/32322
Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
Tested-by: Kohei Yoshida <libreoffice at kohei.us>
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 25e3c4b..2603cd6 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -83,6 +83,7 @@ struct ReorderParam;
class FormulaGroupAreaListener;
class ColumnSet;
class UpdatedRangeNames;
+class TableColumnBlockPositionSet;
}
@@ -284,6 +285,7 @@ friend class sc::DocumentStreamAccess;
friend class sc::ColumnSpanSet;
friend class sc::EditTextIterator;
friend class sc::FormulaGroupAreaListener;
+friend class sc::TableColumnBlockPositionSet;
typedef std::vector<ScTable*> TableContainer;
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index 1d8641a..96dbc12 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -62,6 +62,12 @@ public:
ScDocument& getDoc();
const ScDocument& getDoc() const;
+ /**
+ * Initialize the storage for all sheets after all the sheet instances
+ * have been created in the document.
+ */
+ void initForSheets();
+
void setDefaultNumericScript(SvtScriptType nScript);
/**
diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index ae3a91a..ce1f4f53 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -33,6 +33,7 @@
#include <mdds/multi_type_vector_custom_func3.hpp>
#include <unordered_map>
+#include <memory>
class ScDocument;
class ScColumn;
@@ -154,6 +155,22 @@ public:
void clear();
};
+/**
+ * Set of column block positions only for one table.
+ */
+class TableColumnBlockPositionSet
+{
+ struct Impl;
+ std::unique_ptr<Impl> mpImpl;
+
+public:
+ TableColumnBlockPositionSet( ScDocument& rDoc, SCTAB nTab );
+ TableColumnBlockPositionSet( TableColumnBlockPositionSet&& rOther );
+ ~TableColumnBlockPositionSet();
+
+ ColumnBlockPosition* getBlockPosition( SCCOL nCol );
+};
+
ScRefCellValue toRefCell( const sc::CellStoreType::const_iterator& itPos, size_t nOffset );
}
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index 69f66cd..7c6ec98 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -48,19 +48,23 @@ struct ScDocumentImportImpl
{
ScDocument& mrDoc;
sc::StartListeningContext maListenCxt;
- sc::ColumnBlockPositionSet maBlockPosSet;
+ std::vector<sc::TableColumnBlockPositionSet> maBlockPosSet;
SvtScriptType mnDefaultScriptNumeric;
std::vector<TabAttr> maTabAttrs;
explicit ScDocumentImportImpl(ScDocument& rDoc) :
mrDoc(rDoc),
maListenCxt(rDoc),
- maBlockPosSet(rDoc),
mnDefaultScriptNumeric(SvtScriptType::UNKNOWN) {}
+ static bool isValid( size_t nTab, size_t nCol )
+ {
+ return (nTab <= size_t(MAXTAB) && nCol <= size_t(MAXCOL));
+ }
+
ColAttr* getColAttr( size_t nTab, size_t nCol )
{
- if (nTab > static_cast<size_t>(MAXTAB) || nCol > static_cast<size_t>(MAXCOL))
+ if (!isValid(nTab, nCol))
return nullptr;
if (nTab >= maTabAttrs.size())
@@ -72,6 +76,31 @@ struct ScDocumentImportImpl
return &rTab.maCols[nCol];
}
+
+ sc::ColumnBlockPosition* getBlockPosition( SCTAB nTab, SCCOL nCol )
+ {
+ if (!isValid(nTab, nCol))
+ return nullptr;
+
+ if (size_t(nTab) >= maBlockPosSet.size())
+ {
+ for (SCTAB i = maBlockPosSet.size(); i <= nTab; ++i)
+ maBlockPosSet.emplace_back(mrDoc, i);
+ }
+
+ sc::TableColumnBlockPositionSet& rTab = maBlockPosSet[nTab];
+ return rTab.getBlockPosition(nCol);
+ }
+
+ void initForSheets()
+ {
+ size_t n = mrDoc.GetTableCount();
+ for (size_t i = maBlockPosSet.size(); i < n; ++i)
+ maBlockPosSet.emplace_back(mrDoc, i);
+
+ if (maTabAttrs.size() < n)
+ maTabAttrs.resize(n);
+ }
};
ScDocumentImport::Attrs::Attrs() : mpData(nullptr), mnSize(0), mbLatinNumFmtOnly(false) {}
@@ -92,6 +121,11 @@ const ScDocument& ScDocumentImport::getDoc() const
return mpImpl->mrDoc;
}
+void ScDocumentImport::initForSheets()
+{
+ mpImpl->initForSheets();
+}
+
void ScDocumentImport::setDefaultNumericScript(SvtScriptType nScript)
{
mpImpl->mnDefaultScriptNumeric = nScript;
@@ -144,8 +178,7 @@ void ScDocumentImport::setAutoInput(const ScAddress& rPos, const OUString& rStr,
if (!pTab)
return;
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
if (!pBlockPos)
return;
@@ -185,8 +218,7 @@ void ScDocumentImport::setNumericCell(const ScAddress& rPos, double fVal)
if (!pTab)
return;
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
if (!pBlockPos)
return;
@@ -201,8 +233,7 @@ void ScDocumentImport::setStringCell(const ScAddress& rPos, const OUString& rStr
if (!pTab)
return;
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
if (!pBlockPos)
return;
@@ -221,8 +252,7 @@ void ScDocumentImport::setEditCell(const ScAddress& rPos, EditTextObject* pEditT
if (!pTab)
return;
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
if (!pBlockPos)
return;
@@ -239,8 +269,7 @@ void ScDocumentImport::setFormulaCell(
if (!pTab)
return;
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
if (!pBlockPos)
return;
@@ -256,8 +285,7 @@ void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScTokenArray* pArra
if (!pTab)
return;
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
if (!pBlockPos)
return;
@@ -273,8 +301,7 @@ void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCel
if (!pTab)
return;
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
if (!pBlockPos)
return;
@@ -293,8 +320,7 @@ void ScDocumentImport::setMatrixCells(
if (!pTab)
return;
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(rBasePos.Tab(), rBasePos.Col());
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rBasePos.Tab(), rBasePos.Col());
if (!pBlockPos)
return;
@@ -338,7 +364,7 @@ void ScDocumentImport::setMatrixCells(
for (SCCOL nCol = rRange.aStart.Col()+1; nCol <= rRange.aEnd.Col(); ++nCol)
{
- pBlockPos = mpImpl->maBlockPosSet.getBlockPosition(rBasePos.Tab(), nCol);
+ pBlockPos = mpImpl->getBlockPosition(rBasePos.Tab(), nCol);
if (!pBlockPos)
return;
@@ -429,8 +455,7 @@ void ScDocumentImport::setTableOpCells(const ScRange& rRange, const ScTabOpParam
for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
{
- sc::ColumnBlockPosition* pBlockPos =
- mpImpl->maBlockPosSet.getBlockPosition(nTab, nCol);
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(nTab, nCol);
if (!pBlockPos)
// Something went horribly wrong.
diff --git a/sc/source/core/data/mtvelements.cxx b/sc/source/core/data/mtvelements.cxx
index cf436ba..0bb50aa 100644
--- a/sc/source/core/data/mtvelements.cxx
+++ b/sc/source/core/data/mtvelements.cxx
@@ -12,6 +12,11 @@
#include "document.hxx"
#include "cellvalue.hxx"
#include "column.hxx"
+#include <table.hxx>
+
+#include <o3tl/make_unique.hxx>
+
+#include <sstream>
namespace sc {
@@ -96,6 +101,60 @@ void ColumnBlockPositionSet::clear()
maTables.clear();
}
+struct TableColumnBlockPositionSet::Impl
+{
+ typedef std::unordered_map<SCCOL, ColumnBlockPosition> ColumnsType;
+
+ ScTable* mpTab;
+ ColumnsType maColumns;
+
+ Impl() : mpTab(nullptr) {}
+};
+
+TableColumnBlockPositionSet::TableColumnBlockPositionSet( ScDocument& rDoc, SCTAB nTab ) :
+ mpImpl(o3tl::make_unique<Impl>())
+{
+ mpImpl->mpTab = rDoc.FetchTable(nTab);
+
+ if (!mpImpl->mpTab)
+ {
+ std::ostringstream os;
+ os << "Passed table index " << nTab << " is invalid.";
+ throw std::invalid_argument(os.str());
+ }
+}
+
+TableColumnBlockPositionSet::TableColumnBlockPositionSet( TableColumnBlockPositionSet&& rOther ) :
+ mpImpl(std::move(rOther.mpImpl)) {}
+
+TableColumnBlockPositionSet::~TableColumnBlockPositionSet() {}
+
+ColumnBlockPosition* TableColumnBlockPositionSet::getBlockPosition( SCCOL nCol )
+{
+ using ColumnsType = Impl::ColumnsType;
+
+ ColumnsType::iterator it = mpImpl->maColumns.find(nCol);
+
+ if (it != mpImpl->maColumns.end())
+ // Block position for this column has already been fetched.
+ return &it->second;
+
+ std::pair<ColumnsType::iterator,bool> r =
+ mpImpl->maColumns.insert(
+ ColumnsType::value_type(nCol, ColumnBlockPosition()));
+
+ if (!r.second)
+ // insertion failed.
+ return nullptr;
+
+ it = r.first;
+
+ if (!mpImpl->mpTab->InitColumnBlockPosition(it->second, nCol))
+ return nullptr;
+
+ return &it->second;
+}
+
ScRefCellValue toRefCell( const sc::CellStoreType::const_iterator& itPos, size_t nOffset )
{
switch (itPos->type)
diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index cb6d298..add959c 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -309,6 +309,8 @@ public:
void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVector& rSheets )
{
+ rWorkbookHandler.getDocImport().initForSheets();
+
Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
// test sequential read in this mode
More information about the Libreoffice-commits
mailing list