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

Kohei Yoshida kohei.yoshida at collabora.com
Fri Nov 15 07:37:23 PST 2013


 sc/inc/tokenstringcontext.hxx              |   11 ++++++-
 sc/qa/unit/ucalc_formula.cxx               |   30 ++++++++++++++++++--
 sc/source/core/tool/token.cxx              |   43 ++++++++++++++++++-----------
 sc/source/core/tool/tokenstringcontext.cxx |   18 +++++++++++-
 sc/source/filter/oox/formulabuffer.cxx     |   12 ++++----
 5 files changed, 86 insertions(+), 28 deletions(-)

New commits:
commit cf3977c605cca29e35a9079a3c5c118f4d22fc39
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 15 10:37:26 2013 -0500

    Handle global range names and use CreateString() during xlsx import.
    
    This makes the load speed slightly faster.
    
    Change-Id: I64e4d4b8c42a68577350539f3812cafdc0433f96

diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx
index e5bb01c..5bcc3b3 100644
--- a/sc/inc/tokenstringcontext.hxx
+++ b/sc/inc/tokenstringcontext.hxx
@@ -12,6 +12,10 @@
 
 #include "compiler.hxx"
 
+#include <boost/unordered_map.hpp>
+
+class ScDocument;
+
 namespace sc {
 
 /**
@@ -20,16 +24,19 @@ namespace sc {
  * between multiple CreateString() calls as long as the document content is
  * unmodified.
  */
-struct TokenStringContext
+struct SC_DLLPUBLIC TokenStringContext
 {
+    typedef boost::unordered_map<sal_uInt16, OUString> IndexNameMapType;
+
     formula::FormulaGrammar::Grammar meGram;
     formula::FormulaCompiler::OpCodeMapPtr mxOpCodeMap;
     const ScCompiler::Convention* mpRefConv;
     OUString maErrRef;
 
     std::vector<OUString> maTabNames;
+    IndexNameMapType maGlobalRangeNames;
 
-    TokenStringContext( formula::FormulaGrammar::Grammar eGram );
+    TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram );
 };
 
 }
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 1f867f1..43e0d1d 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -32,6 +32,7 @@ using namespace formula;
 
 void Test::testFormulaCreateStringFromTokens()
 {
+    // Insert sheets.
     OUString aTabName1("Test");
     OUString aTabName2("Kevin's Data");
     OUString aTabName3("Past Data");
@@ -41,19 +42,42 @@ void Test::testFormulaCreateStringFromTokens()
     m_pDoc->InsertTab(2, aTabName3);
     m_pDoc->InsertTab(3, aTabName4);
 
+    // Insert named ranges.
+    struct {
+        const char* pName;
+        const char* pExpr;
+    } aNames[] = {
+        { "x", "Test.H1" },
+        { "y", "Test.H2" },
+        { "z", "Test.H3" }
+    };
+
+    ScRangeName* pGlobalNames = m_pDoc->GetRangeName();
+    CPPUNIT_ASSERT_MESSAGE("Failed to obtain global named expression object.", pGlobalNames);
+
+    for (size_t i = 0, n = SAL_N_ELEMENTS(aNames); i < n; ++i)
+    {
+        ScRangeData* pName = new ScRangeData(
+            m_pDoc, OUString::createFromAscii(aNames[i].pName), OUString::createFromAscii(aNames[i].pExpr),
+            ScAddress(0,0,0), RT_NAME, formula::FormulaGrammar::GRAM_NATIVE);
+
+        bool bInserted = pGlobalNames->insert(pName);
+        CPPUNIT_ASSERT_MESSAGE("Failed to insert a new name.", bInserted);
+    }
+
     const char* aTests[] = {
         "1+2",
         "SUM(A1:A10;B1:B10;C5;D6)",
         "IF(Test.B10<>10;\"Good\";\"Bad\")",
         "AVERAGE('2013'.B10:C20)",
         "'Kevin''s Data'.B10",
-        "'Past Data'.B1+'2013'.B2*(1+'Kevin''s Data'.C10)"
+        "'Past Data'.B1+'2013'.B2*(1+'Kevin''s Data'.C10)",
+        "x+y*z"
     };
 
     boost::scoped_ptr<ScTokenArray> pArray;
 
-    sc::TokenStringContext aCxt(formula::FormulaGrammar::GRAM_ENGLISH);
-    aCxt.maTabNames = m_pDoc->GetAllTableNames();
+    sc::TokenStringContext aCxt(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH);
     ScAddress aPos(0,0,0);
 
     for (size_t i = 0, n = SAL_N_ELEMENTS(aTests); i < n; ++i)
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index a226549..8984632 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3222,7 +3222,22 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
             // TODO : Implement this.
         break;
         case svIndex:
-            // TODO : Implement this.
+        {
+            sal_uInt16 nIndex = rToken.GetIndex();
+            switch (eOp)
+            {
+                case ocName:
+                {
+                    sc::TokenStringContext::IndexNameMapType::const_iterator it = rCxt.maGlobalRangeNames.find(nIndex);
+                    if (it != rCxt.maGlobalRangeNames.end())
+                        rBuf.append(it->second);
+                }
+                break;
+                    // TODO : Handle other name types.
+                default:
+                    ;
+            }
+        }
         break;
         case svExternal:
             // TODO : Implement this.
@@ -3284,23 +3299,19 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre
     {
         const FormulaToken* pToken = *p;
         OpCode eOp = pToken->GetOpCode();
-        switch (eOp)
+        bool bCheckType = true;
+        if (eOp == ocSpaces)
         {
-            case ocPush:
-                appendTokenByType(rCxt, aBuf, *pToken, rPos);
-            break;
-            case ocSpaces:
-                // TODO : Handle intersection operator '!!'.
-                aBuf.append(sal_Unicode(' '));
-            break;
-            default:
-            {
-                if (eOp < rCxt.mxOpCodeMap->getSymbolCount())
-                    aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp));
-                else
-                    return OUString();
-            }
+            // TODO : Handle intersection operator '!!'.
+            aBuf.append(' ');
+            continue;
         }
+
+        if (eOp < rCxt.mxOpCodeMap->getSymbolCount())
+            aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp));
+
+        if (bCheckType)
+            appendTokenByType(rCxt, aBuf, *pToken, rPos);
     }
 
     return aBuf.makeStringAndClear();
diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx
index 5fea0a9..b26d338 100644
--- a/sc/source/core/tool/tokenstringcontext.cxx
+++ b/sc/source/core/tool/tokenstringcontext.cxx
@@ -9,12 +9,13 @@
 
 #include "tokenstringcontext.hxx"
 #include "compiler.hxx"
+#include "document.hxx"
 
 using namespace com::sun::star;
 
 namespace sc {
 
-TokenStringContext::TokenStringContext( formula::FormulaGrammar::Grammar eGram ) :
+TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ) :
     meGram(eGram),
     mpRefConv(ScCompiler::GetRefConvention(formula::FormulaGrammar::extractRefConvention(eGram)))
 {
@@ -22,6 +23,21 @@ TokenStringContext::TokenStringContext( formula::FormulaGrammar::Grammar eGram )
     mxOpCodeMap = aComp.GetOpCodeMap(formula::FormulaGrammar::extractFormulaLanguage(eGram));
     if (mxOpCodeMap)
         maErrRef = mxOpCodeMap->getSymbol(ocErrRef);
+
+    if (pDoc)
+    {
+        maTabNames = pDoc->GetAllTableNames();
+        const ScRangeName* pNames = pDoc->GetRangeName();
+        if (pNames)
+        {
+            ScRangeName::const_iterator it = pNames->begin(), itEnd = pNames->end();
+            for (; it != itEnd; ++it)
+            {
+                const ScRangeData* pData = it->second;
+                maGlobalRangeNames.insert(IndexNameMapType::value_type(pData->GetIndex(), pData->GetName()));
+            }
+        }
+    }
 }
 
 }
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 7472d3d..d1cf118 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -25,6 +25,7 @@
 #include "tokenarray.hxx"
 #include "sharedformulagroups.hxx"
 #include "externalrefmgr.hxx"
+#include "tokenstringcontext.hxx"
 #include "oox/token/tokens.hxx"
 
 using namespace com::sun::star;
@@ -56,7 +57,8 @@ public:
         Item() : mnRow(-1), mpCell(NULL) {}
     };
 
-    CachedTokenArray( ScDocument& rDoc ) : mrDoc(rDoc) {}
+    CachedTokenArray( ScDocument& rDoc ) :
+        mrDoc(rDoc), maCxt(&rDoc, formula::FormulaGrammar::GRAM_OOXML) {}
 
     ~CachedTokenArray()
     {
@@ -73,11 +75,8 @@ public:
             return NULL;
 
         Item& rCached = *it->second;
-        ScCompiler aComp(&mrDoc, rPos, *rCached.mpCell->GetCode());
-        aComp.SetGrammar(formula::FormulaGrammar::GRAM_OOXML);
-        OUStringBuffer aBuf;
-        aComp.CreateStringFromTokenArray(aBuf);
-        OUString aPredicted = aBuf.makeStringAndClear();
+        const ScTokenArray& rCode = *rCached.mpCell->GetCode();
+        OUString aPredicted = rCode.CreateString(maCxt, rPos);
         if (rFormula == aPredicted)
             return &rCached;
 
@@ -108,6 +107,7 @@ private:
     typedef boost::unordered_map<SCCOL, Item*> ColCacheType;
     ColCacheType maCache;
     ScDocument& mrDoc;
+    sc::TokenStringContext maCxt;
 };
 
 void applySharedFormulas(


More information about the Libreoffice-commits mailing list