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

Eike Rathke erack at redhat.com
Tue Aug 18 02:38:16 PDT 2015


 sc/source/core/data/document.cxx    |    8 ++
 sc/source/core/data/formulacell.cxx |  133 ++++++++++++++++++++++++++++++++++++
 2 files changed, 141 insertions(+)

New commits:
commit f7e493229bd949066b4d8984dce7678b8687d1ae
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Aug 18 11:33:44 2015 +0200

    Resolves: tdf#92749 invalidate lookup caches after initial hard recalc
    
    ... because the caches are not setup as listeners during when the
    document's hard recalc state is active.
    
    Change-Id: Ie7ec84ee64d046e3e55ce26b92824e94a2f660e9

diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 7943fa5..b0b3aa3 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3780,6 +3780,14 @@ void ScDocument::CalcAll()
         if (*it)
             (*it)->CalcAll();
     ClearFormulaTree();
+
+    // In hard recalc state caches were not added as listeners, invalidate them
+    // so the next non-CalcAll() normal lookup will not be presented with
+    // outdated data.
+    /* TODO: come up with more detailed hard recalc states so we can
+     * differentiate between hard recalc after load and others. */
+    if (GetHardRecalcState())
+        ClearLookupCaches();
 }
 
 void ScDocument::CompileAll()
commit a962d699b044ee1688e914873c72337fa6217619
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Aug 18 11:32:05 2015 +0200

    add a simple formula cell calculation chain dumper
    
    Change-Id: Ie6409724dcf0baa2f1d7dd62ed8d995f0374dbf1

diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index c90ab3e..bfda996 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -70,6 +70,121 @@ using namespace formula;
 IMPL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
 #endif
 
+#define DEBUG_CALCULATION 0
+#if DEBUG_CALCULATION
+static ScAddress aDebugCalculationTriggerAddress(1,2,0);    // Sheet1.B3, whatever you like
+
+struct DebugCalculationEntry
+{
+          ScAddress     maPos;
+          OUString      maResult;
+    const ScDocument*   mpDoc;
+
+    DebugCalculationEntry( const ScAddress& rPos, const ScDocument* pDoc ) :
+        maPos(rPos),
+        mpDoc(pDoc)
+    {
+    }
+};
+
+/** Debug/dump formula cell calculation chain.
+    Either, somewhere set aDC.mbActive=true, or
+    aDC.maTrigger=ScAddress(col,row,tab) of interest from where to start.
+    This does not work for deep recursion > MAXRECURSION, the results are
+    somewhat.. funny.. ;)
+ */
+static struct DebugCalculation
+{
+    std::vector< DebugCalculationEntry >    mvPos;
+    std::vector< DebugCalculationEntry >    mvResults;
+    ScAddress                               maTrigger;
+    bool                                    mbActive;
+    bool                                    mbSwitchOff;
+    bool                                    mbPrint;
+    bool                                    mbPrintResults;
+
+    DebugCalculation() : mbActive(false), mbSwitchOff(false), mbPrint(true), mbPrintResults(false) {}
+
+    /** Print chain in encountered dependency order. */
+    void print() const
+    {
+        for (auto const& it : mvPos)
+        {
+            OUString aStr( it.maPos.Format( SCA_VALID | SCA_TAB_3D, it.mpDoc));
+            fprintf( stderr, "%s -> ", aStr.toUtf8().getStr());
+        }
+        fprintf( stderr, "%s", "END\n");
+    }
+
+    /** Print chain results. */
+    void printResults() const
+    {
+        for (auto const& it : mvResults)
+        {
+            OUString aStr( it.maPos.Format( SCA_VALID | SCA_TAB_3D, it.mpDoc));
+            aStr += "(" + it.maResult + ")";
+            fprintf( stderr, "%s, ", aStr.toUtf8().getStr());
+        }
+        fprintf( stderr, "%s", "END\n");
+    }
+
+    void storeResult( const svl::SharedString& rStr )
+    {
+        if (mbActive && !mvPos.empty())
+            mvPos.back().maResult = rStr.getString();
+    }
+
+    void storeResult( const double& fVal )
+    {
+        if (mbActive && !mvPos.empty())
+            storeResult( rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 2, '.', true));
+    }
+
+} aDC;
+
+struct DebugCalculationStacker
+{
+    DebugCalculationStacker( const ScAddress& rPos, const ScDocument* pDoc )
+    {
+        if (!aDC.mbActive && rPos == aDC.maTrigger)
+            aDC.mbActive = aDC.mbSwitchOff = true;
+        if (aDC.mbActive)
+        {
+            aDC.mvPos.push_back( DebugCalculationEntry( rPos, pDoc));
+            aDC.mbPrint = true;
+        }
+    }
+
+    ~DebugCalculationStacker()
+    {
+        if (aDC.mbActive)
+        {
+            if (!aDC.mvPos.empty())
+            {
+                if (aDC.mbPrint)
+                {
+                    aDC.print();
+                    aDC.mbPrint = false;
+                }
+                if (aDC.mbPrintResults)
+                {
+                    // Store results until final result is available, reversing order.
+                    aDC.mvResults.push_back( aDC.mvPos.back());
+                }
+                aDC.mvPos.pop_back();
+                if (aDC.mbPrintResults && aDC.mvPos.empty())
+                {
+                    aDC.printResults();
+                    std::vector< DebugCalculationEntry >().swap( aDC.mvResults);
+                }
+                if (aDC.mbSwitchOff && aDC.mvPos.empty())
+                    aDC.mbActive = false;
+            }
+        }
+    }
+};
+#endif
+
 namespace {
 
 // More or less arbitrary, of course all recursions must fit into available
@@ -1432,6 +1547,17 @@ bool ScFormulaCell::MarkUsedExternalReferences()
 
 void ScFormulaCell::Interpret()
 {
+#if DEBUG_CALCULATION
+    static bool bDebugCalculationInit = true;
+    if (bDebugCalculationInit)
+    {
+        aDC.maTrigger = aDebugCalculationTriggerAddress;
+        aDC.mbPrintResults = true;
+        bDebugCalculationInit = false;
+    }
+    DebugCalculationStacker aDebugEntry( aPos, pDocument);
+#endif
+
     if (!IsDirtyOrInTableOpDirty() || pDocument->GetRecursionHelper().IsInReturn())
         return;     // no double/triple processing
 
@@ -1660,6 +1786,13 @@ void ScFormulaCell::Interpret()
             }
         } while (bIterationFromRecursion || bResumeIteration);
     }
+
+#if DEBUG_CALCULATION
+    if (aResult.IsValue())
+        aDC.storeResult( aResult.GetDouble());
+    else
+        aDC.storeResult( aResult.GetString());
+#endif
 }
 
 void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )


More information about the Libreoffice-commits mailing list