[Libreoffice-commits] core.git: Branch 'private/kohei/external-ref-refresh' - 2 commits - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Tue May 20 11:10:49 PDT 2014


 sc/inc/externalrefmgr.hxx                |   24 ++++
 sc/inc/sc.hrc                            |    3 
 sc/source/core/data/documen8.cxx         |    2 
 sc/source/ui/docshell/externalrefmgr.cxx |  170 ++++++++++++++++++++++++++++++-
 sc/source/ui/src/scstring.src            |    5 
 5 files changed, 197 insertions(+), 7 deletions(-)

New commits:
commit 36162e779da890e99c962563d060355c72a2b8e5
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue May 20 13:57:13 2014 -0400

    cp#1000072: Populate cache tables when updating all external links.
    
    This way, even after the loaded doc shells get purged due to timeout,
    we won't reload those external documents from disk again.  One caveat
    is that we currently don't pre-populate empty cells even if they are
    referenced by the host document.
    
    Change-Id: I1de2987836bf2fc5d9d7044b406fb99faa534164

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index bbb3094..9bcc64d 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -55,6 +55,12 @@ class SharedStringPool;
 
 }
 
+namespace sc {
+
+class ColumnSpanSet;
+
+}
+
 class ScExternalRefLink : public ::sfx2::SvBaseLink
 {
 public:
@@ -145,6 +151,8 @@ public:
         Table();
         ~Table();
 
+        void clear();
+
         /**
          * Add cell value to the cache.
          *
@@ -268,6 +276,13 @@ public:
     void setAllCacheTableReferencedStati( bool bReferenced );
     bool areAllCacheTablesReferenced() const;
 
+    /**
+     * Collect all cached non-empty cell positions, inferred directly from the
+     * cached data, not the cached range metadata stored separately in the
+     * Table.
+     */
+    void getAllCachedDataSpans( sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const;
+
 private:
     struct ReferencedStatus
     {
@@ -295,8 +310,17 @@ public:
     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew, size_t* pnIndex);
 
+    /**
+     * Clear all caches including the cache tables.
+     */
     void clearCache(sal_uInt16 nFileId);
 
+    /**
+     * Clear all caches but keep the tables.  All cache tables will be empty
+     * after the call, but the tables will not be removed.
+     */
+    void clearCacheTables(sal_uInt16 nFileId);
+
 private:
     struct RangeHash
     {
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 525bbce..9f6b657 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -53,6 +53,8 @@
 #include <vcl/msgbox.hxx>
 #include "stringutil.hxx"
 #include "scmatrix.hxx"
+#include <columnspanset.hxx>
+#include <column.hxx>
 
 #include <memory>
 #include <algorithm>
@@ -254,6 +256,13 @@ ScExternalRefCache::Table::~Table()
 {
 }
 
+void ScExternalRefCache::Table::clear()
+{
+    maRows.clear();
+    maCachedRanges.RemoveAll();
+    meReferenced = REFERENCED_MARKED;
+}
+
 void ScExternalRefCache::Table::setReferencedFlag( ScExternalRefCache::Table::ReferencedFlag eFlag )
 {
     meReferenced = eFlag;
@@ -445,9 +454,6 @@ void ScExternalRefCache::Table::setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCC
         maCachedRanges.Append(aRange);
     else
         maCachedRanges.Join(aRange);
-
-    OUString aStr;
-    maCachedRanges.Format(aStr, SCA_VALID);
 }
 
 void ScExternalRefCache::Table::setWholeTableCached()
@@ -1106,6 +1112,35 @@ bool ScExternalRefCache::areAllCacheTablesReferenced() const
     return maReferenced.mbAllReferenced;
 }
 
+void ScExternalRefCache::getAllCachedDataSpans( sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const
+{
+    const DocItem* pDocItem = getDocItem(nFileId);
+    if (!pDocItem)
+        // This document is not cached.
+        return;
+
+    const std::vector<TableTypeRef>& rTables = pDocItem->maTables;
+    for (size_t nTab = 0, nTabCount = rTables.size(); nTab < nTabCount; ++nTab)
+    {
+        const Table& rTable = *rTables[nTab];
+        std::vector<SCROW> aRows;
+        rTable.getAllRows(aRows);
+        std::vector<SCROW>::const_iterator itRow = aRows.begin(), itRowEnd = aRows.end();
+        for (; itRow != itRowEnd; ++itRow)
+        {
+            SCROW nRow = *itRow;
+            std::vector<SCCOL> aCols;
+            rTable.getAllCols(nRow, aCols);
+            std::vector<SCCOL>::const_iterator itCol = aCols.begin(), itColEnd = aCols.end();
+            for (; itCol != itColEnd; ++itCol)
+            {
+                SCCOL nCol = *itCol;
+                rSet.set(nTab, nCol, nRow, true);
+            }
+        }
+    }
+}
+
 ScExternalRefCache::ReferencedStatus::ReferencedStatus() :
     mbAllReferenced(false)
 {
@@ -1199,6 +1234,28 @@ void ScExternalRefCache::clearCache(sal_uInt16 nFileId)
     maDocs.erase(nFileId);
 }
 
+void ScExternalRefCache::clearCacheTables(sal_uInt16 nFileId)
+{
+    osl::MutexGuard aGuard(&maMtxDocs);
+    DocItem* pDocItem = getDocItem(nFileId);
+    if (!pDocItem)
+        // This document is not cached at all.
+        return;
+
+    // Clear all cache table content, but keep the tables.
+    std::vector<TableTypeRef>& rTabs = pDocItem->maTables;
+    for (size_t i = 0, n = rTabs.size(); i < n; ++i)
+    {
+        Table& rTab = *rTabs[i];
+        rTab.clear();
+    }
+
+    // Clear the external range name caches.
+    pDocItem->maRangeNames.clear();
+    pDocItem->maRangeArrays.clear();
+    pDocItem->maRealRangeNameMap.clear();
+}
+
 ScExternalRefCache::DocItem* ScExternalRefCache::getDocItem(sal_uInt16 nFileId) const
 {
     osl::MutexGuard aGuard(&maMtxDocs);
@@ -1864,6 +1921,7 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
 
         // Put the data into cache.
         putRangeDataIntoCache(maRefCache, pArray, nFileId, rTabName, aCacheData, rRange, aDataRange);
+        fprintf(stdout, "ScExternalRefManager::getDoubleRefTokens:   in memory!\n");
         return pArray;
     }
 
@@ -1871,8 +1929,11 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
     ScExternalRefCache::TokenArrayRef pArray =
         maRefCache.getCellRangeData(nFileId, rTabName, rRange);
     if (pArray)
+    {
         // Cache hit !
+        fprintf(stdout, "ScExternalRefManager::getDoubleRefTokens:   cached!\n");
         return pArray;
+    }
 
     pSrcDoc = getSrcDocument(nFileId);
     if (!pSrcDoc)
@@ -2580,8 +2641,100 @@ void ScExternalRefManager::clearCache(sal_uInt16 nFileId)
     maRefCache.clearCache(nFileId);
 }
 
+namespace {
+
+class RefCacheFiller : public sc::ColumnSpanSet::ColumnAction
+{
+    svl::SharedStringPool& mrStrPool;
+
+    ScExternalRefCache& mrRefCache;
+    ScExternalRefCache::TableTypeRef mpRefTab;
+    sal_uInt16 mnFileId;
+    ScColumn* mpCurCol;
+    sc::ColumnBlockConstPosition maBlockPos;
+
+public:
+    RefCacheFiller( svl::SharedStringPool& rStrPool, ScExternalRefCache& rRefCache, sal_uInt16 nFileId ) :
+        mrStrPool(rStrPool), mrRefCache(rRefCache), mnFileId(nFileId), mpCurCol(NULL) {}
+
+    virtual void startColumn( ScColumn* pCol )
+    {
+        mpCurCol = pCol;
+        if (!mpCurCol)
+            return;
+
+        mpCurCol->InitBlockPosition(maBlockPos);
+        mpRefTab = mrRefCache.getCacheTable(mnFileId, mpCurCol->GetTab());
+    }
+
+    virtual void execute( SCROW nRow1, SCROW nRow2, bool bVal )
+    {
+        if (!mpCurCol || !bVal)
+            return;
+
+        if (!mpRefTab)
+            return;
+
+        for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+        {
+            ScExternalRefCache::TokenRef pTok;
+            ScRefCellValue aCell = mpCurCol->GetCellValue(maBlockPos, nRow);
+            switch (aCell.meType)
+            {
+                case CELLTYPE_STRING:
+                case CELLTYPE_EDIT:
+                {
+                    OUString aStr = aCell.getString(&mpCurCol->GetDoc());
+                    svl::SharedString aSS = mrStrPool.intern(aStr);
+                    pTok.reset(new formula::FormulaStringToken(aSS));
+                }
+                break;
+                case CELLTYPE_VALUE:
+                    pTok.reset(new formula::FormulaDoubleToken(aCell.mfValue));
+                break;
+                case CELLTYPE_FORMULA:
+                {
+                    sc::FormulaResultValue aRes = aCell.mpFormula->GetResult();
+                    switch (aRes.meType)
+                    {
+                        case sc::FormulaResultValue::Value:
+                            pTok.reset(new formula::FormulaDoubleToken(aRes.mfValue));
+                        break;
+                        case sc::FormulaResultValue::String:
+                        {
+                            // Re-intern the string to the host document pool.
+                            svl::SharedString aInterned = mrStrPool.intern(aRes.maString.getString());
+                            pTok.reset(new formula::FormulaStringToken(aInterned));
+                        }
+                        break;
+                        case sc::FormulaResultValue::Error:
+                        case sc::FormulaResultValue::Invalid:
+                        default:
+                            pTok.reset(new FormulaErrorToken(errNoValue));
+                    }
+                }
+                break;
+                default:
+                    pTok.reset(new FormulaErrorToken(errNoValue));
+            }
+
+            if (pTok)
+            {
+                // Cache this cell.
+                mpRefTab->setCell(mpCurCol->GetCol(), nRow, pTok, mpCurCol->GetNumberFormat(nRow));
+                mpRefTab->setCachedCell(mpCurCol->GetCol(), nRow);
+            }
+        }
+    };
+};
+
+}
+
 bool ScExternalRefManager::refreshSrcDocument(sal_uInt16 nFileId)
 {
+    sc::ColumnSpanSet aCachedArea(false);
+    maRefCache.getAllCachedDataSpans(nFileId, aCachedArea);
+
     OUString aFilter;
     SfxObjectShellRef xDocShell;
     try
@@ -2594,8 +2747,15 @@ bool ScExternalRefManager::refreshSrcDocument(sal_uInt16 nFileId)
         // Failed to load the document.  Bail out.
         return false;
 
-    // Clear the existing cache, and store the loaded doc shell until it expires.
-    clearCache(nFileId);
+    ScDocShell& rDocSh = static_cast<ScDocShell&>(*xDocShell);
+    ScDocument* pSrcDoc = rDocSh.GetDocument();
+
+    // Clear the existing cache, and refill it.  Make sure we keep the
+    // existing cache table instances here.
+    maRefCache.clearCacheTables(nFileId);
+    RefCacheFiller aAction(mpDoc->GetSharedStringPool(), maRefCache, nFileId);
+    aCachedArea.executeColumnAction(*pSrcDoc, aAction);
+
     DocShellMap::iterator it = maDocShells.find(nFileId);
     if (it != maDocShells.end())
     {
commit 1180143cf031035b585424eb58ed3884ec6435f3
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue May 20 10:41:03 2014 -0400

    Localize this string.
    
    Change-Id: I88b205d36eede5e63af46f8581896d980b6aa27d

diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index d350aad..2253aac 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -983,7 +983,8 @@
 #define STR_MID                 (STR_START + 431)
 #define STR_SOUTH               (STR_START + 432)
 #define STR_SUM                 (STR_START + 433)
-#define STR_END                 (STR_SUM)
+#define SCSTR_UPDATE_EXTDOCS    (STR_START + 434)
+#define STR_END                 (SCSTR_UPDATE_EXTDOCS)
 
 #define BMP_START               (STR_END)
 
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 6b2f028..e8ce20c 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -803,7 +803,7 @@ void ScDocument::UpdateExternalRefLinks(Window* pWin)
     }
 
     pExternalRefMgr->enableDocTimer(false);
-    ScProgress aProgress(GetDocumentShell(), "Updating external links", aRefLinks.size());
+    ScProgress aProgress(GetDocumentShell(), ScResId(SCSTR_UPDATE_EXTDOCS).toString(), aRefLinks.size());
     for (size_t i = 0, n = aRefLinks.size(); i < n; ++i)
     {
         aProgress.SetState(i+1);
diff --git a/sc/source/ui/src/scstring.src b/sc/source/ui/src/scstring.src
index 78d9541..b083fff 100644
--- a/sc/source/ui/src/scstring.src
+++ b/sc/source/ui/src/scstring.src
@@ -811,6 +811,11 @@ String SCSTR_EXTDOC_NOT_LOADED
     Text [ en-US ] = "The following external file could not be loaded. Data linked from this file did not get updated." ;
 };
 
+String SCSTR_UPDATE_EXTDOCS
+{
+    Text [ en-US ] = "Updating external links.";
+};
+
 String SCSTR_FORMULA_SYNTAX_CALC_A1
 {
     Text [ en-US ] = "Calc A1";


More information about the Libreoffice-commits mailing list