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.yosh...@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 <libreoff...@kohei.us> Tested-by: Kohei Yoshida <libreoff...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits