[Libreoffice-commits] core.git: sc/inc sc/source

László Németh laszlo.nemeth at collabora.com
Tue Feb 10 02:13:13 PST 2015


 sc/inc/tokenarray.hxx              |    2 -
 sc/source/core/tool/token.cxx      |   40 +++++++++++++++++++++++++++----------
 sc/source/filter/excel/excform.cxx |    9 ++++++--
 3 files changed, 38 insertions(+), 13 deletions(-)

New commits:
commit b18b5b7edf3d14ef5f0efe53e367f88a423088c4
Author: László Németh <laszlo.nemeth at collabora.com>
Date:   Tue Feb 10 10:25:13 2015 +0100

    tdf#89281 fix performance regression of XLS import
    
    The fix for Bug 76611 caused ~20% performance loss in XLS import.
    With optional cloning of ScTokenArray of the shared XLS formulas
    depending on the need of address wrapping, it is possible to gain
    back near the original performance.
    
    Note: The original patch for Bug 76611 has already got an unit test,
    too (see wrapped-refs.xls), and that unit test works with this
    improved patch, too.
    
    Change-Id: Ibfb59d1543ef9c4b8a075d5c4e37f77ab451aaa0

diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index ab1e941..d1a4bed 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -239,7 +239,7 @@ public:
      */
     OUString CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const;
 
-    void WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow );
+    bool WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow, bool bQueryNeedWrap = false);
 
 #if DEBUG_FORMULA_COMPILER
     void Dump() const;
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index e7e6ece..563b200 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3994,17 +3994,27 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre
 
 namespace {
 
-void wrapAddress( ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow )
+bool wrapAddress( ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow, bool bQueryOnly )
 {
+    bool bChanged = false;
     if (rPos.Col() > nMaxCol)
-        rPos.SetCol(rPos.Col() - nMaxCol - 1);
+    {
+        if (!bQueryOnly)
+            rPos.SetCol(rPos.Col() - nMaxCol - 1);
+        bChanged = true;
+    }
     if (rPos.Row() > nMaxRow)
-        rPos.SetRow(rPos.Row() - nMaxRow - 1);
+    {
+        if (!bQueryOnly)
+            rPos.SetRow(rPos.Row() - nMaxRow - 1);
+        bChanged = true;
+    }
+    return bChanged;
 }
 
 }
 
-void ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow )
+bool ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow, bool bQueryNeedWrap)
 {
     FormulaToken** p = pCode;
     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
@@ -4017,8 +4027,12 @@ void ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nM
                 formula::FormulaToken* pToken = *p;
                 ScSingleRefData& rRef = *pToken->GetSingleRef();
                 ScAddress aAbs = rRef.toAbs(rPos);
-                wrapAddress(aAbs, nMaxCol, nMaxRow);
-                rRef.SetAddress(aAbs, rPos);
+                if (wrapAddress(aAbs, nMaxCol, nMaxRow, bQueryNeedWrap))
+                {
+                    if (bQueryNeedWrap)
+                        return true;
+                    rRef.SetAddress(aAbs, rPos);
+                }
             }
             break;
             case svDoubleRef:
@@ -4026,16 +4040,22 @@ void ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nM
                 formula::FormulaToken* pToken = *p;
                 ScComplexRefData& rRef = *pToken->GetDoubleRef();
                 ScRange aAbs = rRef.toAbs(rPos);
-                wrapAddress(aAbs.aStart, nMaxCol, nMaxRow);
-                wrapAddress(aAbs.aEnd, nMaxCol, nMaxRow);
-                aAbs.PutInOrder();
-                rRef.SetRange(aAbs, rPos);
+                bool bChanged = wrapAddress(aAbs.aStart, nMaxCol, nMaxRow, bQueryNeedWrap);
+                bool bChanged2 = wrapAddress(aAbs.aEnd, nMaxCol, nMaxRow, bQueryNeedWrap);
+                if (bChanged || bChanged2)
+                {
+                    if (bQueryNeedWrap)
+                        return true;
+                    aAbs.PutInOrder();
+                    rRef.SetRange(aAbs, rPos);
+                }
             }
             break;
             default:
                 ;
         }
     }
+    return false;
 }
 
 #if DEBUG_FORMULA_COMPILER
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 22becd6c5..dec9a81 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -122,8 +122,13 @@ void ImportExcel::Formula(
             const ScTokenArray* pSharedCode = pFormConv->GetSharedFormula(aRefPos);
             if (pSharedCode)
             {
-                ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, pSharedCode->Clone());
-                pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8);
+                ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, *pSharedCode);
+                // Do we need to wrap the column or row indices? (tdf#76611)
+                if (pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8, true))
+                {
+                    pCell = new ScFormulaCell(pD, aScPos, pSharedCode->Clone());
+                    pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8);
+                }
                 rDoc.getDoc().EnsureTable(aScPos.Tab());
                 rDoc.setFormulaCell(aScPos, pCell);
                 pCell->SetNeedNumberFormat(false);


More information about the Libreoffice-commits mailing list