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 <er...@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 <er...@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 ) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits