[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