[Libreoffice-commits] core.git: Branch 'private/kohei/xlsx-import-speedup' - 5 commits - include/formula sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Nov 6 01:05:38 CET 2013


 include/formula/token.hxx                |   19 ++++--
 sc/inc/externalrefmgr.hxx                |   35 ++++++++---
 sc/source/core/tool/compiler.cxx         |    2 
 sc/source/ui/docshell/externalrefmgr.cxx |   91 +++++++++++++++++++++++++++++++
 4 files changed, 129 insertions(+), 18 deletions(-)

New commits:
commit 3f04bb5305dc35b34cbec5e4738b3f63c7a10b6b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Nov 5 19:06:15 2013 -0500

    Guard cache access with mutex & a new method just to check for range name.
    
    Change-Id: Id24b5ba72362f9d878b4878c1e807bed3e596b20

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 6156abb..b3d35f9 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -233,6 +233,7 @@ public:
 
     ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName);
     void setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray);
+    bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const;
 
     void setCellData(sal_uInt16 nFileId, const OUString& rTabName,
                      SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uLong nFmtIndex);
@@ -557,6 +558,8 @@ public:
     ScExternalRefCache::TokenArrayRef getRangeNameTokens(
         sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos = NULL);
 
+    bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName);
+
     OUString getOwnDocumentName() const;
     bool isOwnDocument(const OUString& rFile) const;
 
@@ -765,6 +768,12 @@ private:
 private:
     ScDocument* mpDoc;
 
+    /** Mutex for accessing cached data and/or source document shells. */
+    mutable osl::Mutex maMtxCacheAccess;
+
+    /** Mutex for source document meta-data access. */
+    mutable osl::Mutex maMtxSrcFiles;
+
     /** cache of referenced ranges and names from source documents. */
     ScExternalRefCache maRefCache;
 
@@ -798,7 +807,6 @@ private:
      * external document identifiers.
      */
     std::vector<SrcFileData> maSrcFiles;
-    mutable osl::Mutex maMtxSrcFiles;
 
     /** Status whether in reference marking state. See isInReferenceMarking(). */
     bool mbInReferenceMarking:1;
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 5a7d8e2..95e4ef0 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -2914,7 +2914,7 @@ bool ScCompiler::IsExternalNamedRange( const OUString& rSymbol )
     pRefMgr->convertToAbsName(aTmp);
     aFile = aTmp;
     sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFile);
-    if (!pRefMgr->getRangeNameTokens(nFileId, aName).get())
+    if (!pRefMgr->isValidRangeName(nFileId, aName))
         // range name doesn't exist in the source document.
         return false;
 
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 1561cbb..9c07fd7 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -710,6 +710,18 @@ void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const OUString&
     pDoc->maRealRangeNameMap.insert(NamePairMap::value_type(aUpperName, rName));
 }
 
+bool ScExternalRefCache::isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const
+{
+    osl::MutexGuard aGuard(&maMtxDocs);
+
+    DocItem* pDoc = getDocItem(nFileId);
+    if (!pDoc)
+        return false;
+
+    const RangeNameMap& rMap = pDoc->maRangeNames;
+    return rMap.count(rName) > 0;
+}
+
 void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow,
                                      TokenRef pToken, sal_uLong nFmtIndex)
 {
@@ -1747,6 +1759,8 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
     sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell,
     const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt)
 {
+    osl::MutexGuard aGuard(&maMtxCacheAccess);
+
     if (pCurPos)
         insertRefCell(nFileId, *pCurPos);
 
@@ -1839,6 +1853,8 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
 ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
     sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
 {
+    osl::MutexGuard aGuard(&maMtxCacheAccess);
+
     if (pCurPos)
         insertRefCell(nFileId, *pCurPos);
 
@@ -1885,6 +1901,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
 ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(
     sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos)
 {
+    osl::MutexGuard aGuard(&maMtxCacheAccess);
+
     if (pCurPos)
         insertRefCell(nFileId, *pCurPos);
 
@@ -1924,6 +1942,42 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(
     return pArray;
 }
 
+namespace {
+
+bool hasRangeName(ScDocument& rDoc, const OUString& rName)
+{
+    ScRangeName* pExtNames = rDoc.GetRangeName();
+    OUString aUpperName = ScGlobal::pCharClass->uppercase(rName);
+    const ScRangeData* pRangeData = pExtNames->findByUpperName(aUpperName);
+    return pRangeData != NULL;
+}
+
+}
+
+bool ScExternalRefManager::isValidRangeName(sal_uInt16 nFileId, const OUString& rName)
+{
+    osl::MutexGuard aGuard(&maMtxCacheAccess);
+
+    maybeLinkExternalFile(nFileId);
+    ScDocument* pSrcDoc = getInMemorySrcDocument(nFileId);
+    if (pSrcDoc)
+    {
+        // Only check the presence of the name.
+        return hasRangeName(*pSrcDoc, rName);
+    }
+
+    if (maRefCache.isValidRangeName(nFileId, rName))
+        // Range name is cached.
+        return true;
+
+    pSrcDoc = getSrcDocument(nFileId);
+    if (!pSrcDoc)
+        // failed to load document from disk.
+        return false;
+
+    return hasRangeName(*pSrcDoc, rName);
+}
+
 void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
 {
     RefCellMap::iterator itrFile = maRefCells.find(nFileId);
commit c30e006e0633be5eba0a86a8f54bdf9807fe4f91
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Nov 5 17:10:24 2013 -0500

    Add mutex for external source document meta-data container.
    
    These get updated from reference parser code (ScAddress, ScRange etc)
    which may be run from multiple threads.
    
    Change-Id: I5a1aaa4b51d9b9fb032458eb5e89f0652887184e

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index c5a73ae..6156abb 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -793,8 +793,12 @@ private:
 
     NumFmtMap maNumFormatMap;
 
-    /** original source file index. */
-    ::std::vector<SrcFileData> maSrcFiles;
+    /**
+     * List of external source document meta-data, used to keep track of
+     * external document identifiers.
+     */
+    std::vector<SrcFileData> maSrcFiles;
+    mutable osl::Mutex maMtxSrcFiles;
 
     /** Status whether in reference marking state. See isInReferenceMarking(). */
     bool mbInReferenceMarking:1;
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index f7d026b..1561cbb 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -1594,6 +1594,7 @@ void ScExternalRefManager::getAllCachedNumberFormats(vector<sal_uInt32>& rNumFmt
 
 sal_uInt16 ScExternalRefManager::getExternalFileCount() const
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
     return static_cast< sal_uInt16 >( maSrcFiles.size() );
 }
 
@@ -2360,6 +2361,7 @@ void ScExternalRefManager::SrcFileData::maybeCreateRealFileName(const OUString&
 
 void ScExternalRefManager::maybeCreateRealFileName(sal_uInt16 nFileId)
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
     if (nFileId >= maSrcFiles.size())
         return;
 
@@ -2404,6 +2406,8 @@ void ScExternalRefManager::convertToAbsName(OUString& rFile) const
 
 sal_uInt16 ScExternalRefManager::getExternalFileId(const OUString& rFile)
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
+
     vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
     vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
     if (itr != itrEnd)
@@ -2420,6 +2424,8 @@ sal_uInt16 ScExternalRefManager::getExternalFileId(const OUString& rFile)
 
 const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal)
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
+
     if (nFileId >= maSrcFiles.size())
         return NULL;
 
@@ -2436,11 +2442,14 @@ const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bo
 
 bool ScExternalRefManager::hasExternalFile(sal_uInt16 nFileId) const
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
     return nFileId < maSrcFiles.size();
 }
 
 bool ScExternalRefManager::hasExternalFile(const OUString& rFile) const
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
+
     vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
     vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
     return itr != itrEnd;
@@ -2539,6 +2548,8 @@ void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
 
 void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter)
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
+
     maSrcFiles[nFileId].maFileName = rNewFile;
     maSrcFiles[nFileId].maRelativeName = OUString();
     maSrcFiles[nFileId].maRealFileName = OUString();
@@ -2553,6 +2564,8 @@ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNe
 
 void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl)
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
+
     if (nFileId >= maSrcFiles.size())
         return;
     maSrcFiles[nFileId].maRelativeName = rRelUrl;
@@ -2560,6 +2573,8 @@ void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUStrin
 
 void ScExternalRefManager::setFilterData(sal_uInt16 nFileId, const OUString& rFilterName, const OUString& rOptions)
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
+
     if (nFileId >= maSrcFiles.size())
         return;
     maSrcFiles[nFileId].maFilterName = rFilterName;
@@ -2578,11 +2593,13 @@ void ScExternalRefManager::clear()
 
 bool ScExternalRefManager::hasExternalData() const
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
     return !maSrcFiles.empty();
 }
 
 void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl)
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
     for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
           itr != itrEnd; ++itr)
     {
@@ -2598,6 +2615,7 @@ void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl)
 
 void ScExternalRefManager::updateAbsAfterLoad()
 {
+    osl::MutexGuard aGuard(&maMtxSrcFiles);
     OUString aOwn( getOwnDocumentName() );
     for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
           itr != itrEnd; ++itr)
commit aa497840b4c378f4f8d65a9c7c9daec8463e3a21
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Nov 5 16:55:54 2013 -0500

    Make this method private as it is used only internally.
    
    Change-Id: I752c9a6bcd7f5b057cd517a9630a975009d6fb0d

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 21e4e75a..c5a73ae 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -669,14 +669,6 @@ public:
      */
     bool isFileLoadable(const OUString& rFile) const;
 
-    /**
-     * If in maUnsavedDocShells move it to maDocShells and create a correct
-     * external reference entry
-     *
-     * @param Pointer to the newly saved DocumentShell
-     */
-    void transformUnsavedRefToSavedRef( SfxObjectShell* pShell );
-
     virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
 
     /**
@@ -762,6 +754,13 @@ private:
 
     sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc);
 
+    /**
+     * If in maUnsavedDocShells move it to maDocShells and create a correct
+     * external reference entry
+     *
+     * @param Pointer to the newly saved DocumentShell
+     */
+    void transformUnsavedRefToSavedRef( SfxObjectShell* pShell );
 
 private:
     ScDocument* mpDoc;
commit ba5bb8c0cad11d9182065d7ca4d390ee177d670b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Nov 5 16:49:55 2013 -0500

    Set mutex for external ref cache content.
    
    Change-Id: Id00c0e553e08740df8d9b7eef19407e1b0d3f022

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 9ade21d..21e4e75a 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -32,6 +32,7 @@
 #include "types.hxx"
 #include "rangelst.hxx"
 #include "formula/token.hxx"
+#include "osl/mutex.hxx"
 
 #include <boost/unordered_map.hpp>
 #include <boost/unordered_set.hpp>
@@ -340,6 +341,7 @@ private:
     DocItem* getDocItem(sal_uInt16 nFileId) const;
 
 private:
+    mutable osl::Mutex maMtxDocs;
     mutable DocDataType maDocs;
 };
 
@@ -682,7 +684,7 @@ public:
      *
      * @return true if the document still contains references to an unsaved file
      */
-    bool containsUnsavedReferences() { return !maUnsavedDocShells.empty(); }
+    bool containsUnsavedReferences() const { return !maUnsavedDocShells.empty(); }
 
     void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
 
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 676352a..f7d026b 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -494,6 +494,8 @@ ScExternalRefCache::~ScExternalRefCache() {}
 
 const OUString* ScExternalRefCache::getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
     if (itrDoc == maDocs.end())
     {
@@ -515,6 +517,8 @@ const OUString* ScExternalRefCache::getRealTableName(sal_uInt16 nFileId, const O
 
 const OUString* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
     if (itrDoc == maDocs.end())
     {
@@ -535,6 +539,8 @@ const OUString* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const O
 ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
     sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex)
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
     if (itrDoc == maDocs.end())
     {
@@ -564,6 +570,8 @@ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
 ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
     sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange)
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     DocDataType::iterator itrDoc = maDocs.find(nFileId);
     if (itrDoc == maDocs.end())
         // specified document is not cached.
@@ -673,6 +681,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
 
 ScExternalRefCache::TokenArrayRef ScExternalRefCache::getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName)
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     DocItem* pDoc = getDocItem(nFileId);
     if (!pDoc)
         return TokenArrayRef();
@@ -688,6 +698,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getRangeNameTokens(sal_uIn
 
 void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray)
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     DocItem* pDoc = getDocItem(nFileId);
     if (!pDoc)
         return;
@@ -912,6 +924,8 @@ SCsTAB ScExternalRefCache::getTabSpan( sal_uInt16 nFileId, const OUString& rStar
 
 void ScExternalRefCache::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     using ::std::sort;
     using ::std::unique;
 
@@ -986,6 +1000,8 @@ bool ScExternalRefCache::setCacheTableReferenced( sal_uInt16 nFileId, const OUSt
 
 void ScExternalRefCache::setAllCacheTableReferencedStati( bool bReferenced )
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     if (bReferenced)
     {
         maReferenced.reset(0);
@@ -1174,11 +1190,14 @@ ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nF
 
 void ScExternalRefCache::clearCache(sal_uInt16 nFileId)
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
     maDocs.erase(nFileId);
 }
 
 ScExternalRefCache::DocItem* ScExternalRefCache::getDocItem(sal_uInt16 nFileId) const
 {
+    osl::MutexGuard aGuard(&maMtxDocs);
+
     using ::std::pair;
     DocDataType::iterator itrDoc = maDocs.find(nFileId);
     if (itrDoc == maDocs.end())
commit 16880ec68c3d894e721cc98675a67ab2109dc713
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Nov 5 16:25:16 2013 -0500

    Use atomic increment and decrement for thread-safe reference count.
    
    Change-Id: I630298b1c37a6d23c1aa17aabc1c9b2dcb48608a

diff --git a/include/formula/token.hxx b/include/formula/token.hxx
index 8fa8708..ea91e2c 100644
--- a/include/formula/token.hxx
+++ b/include/formula/token.hxx
@@ -29,6 +29,7 @@
 #include "formula/formuladllapi.h"
 #include "formula/types.hxx"
 #include "svl/sharedstring.hxx"
+#include "osl/interlck.h"
 
 namespace formula
 {
@@ -107,12 +108,18 @@ public:
             bool                IsFunction() const; // pure functions, no operators
             bool                IsExternalRef() const;
             sal_uInt8           GetParamCount() const;
-    inline  void                IncRef() const          { nRefCnt++; }
-    inline  void                DecRef() const
-                                    {
-                                        if (!--nRefCnt)
-                                            const_cast<FormulaToken*>(this)->Delete();
-                                    }
+
+    inline void IncRef() const
+    {
+        osl_atomic_increment(&nRefCnt);
+    }
+
+    inline void DecRef() const
+    {
+        if (!osl_atomic_decrement(&nRefCnt))
+            const_cast<FormulaToken*>(this)->Delete();
+    }
+
     inline  sal_uInt16          GetRef() const          { return nRefCnt; }
     inline OpCode               GetOpCode() const       { return eOp; }
 


More information about the Libreoffice-commits mailing list