diff options
author | Dennis Francis <dennis.francis@collabora.co.uk> | 2018-11-08 12:23:00 +0530 |
---|---|---|
committer | Dennis Francis <dennis.francis@collabora.com> | 2018-11-15 09:28:24 +0100 |
commit | 4ddd6f329163cbac5ff31e51a5b028d8eeedadd2 (patch) | |
tree | 61b145e2c032ec6ee1baab92b28d76b24faae4f1 /sc/inc/interpretercontext.hxx | |
parent | 10d497f9cc03e55c0e7119449e119606c40c563e (diff) |
Cache the vConditions array...
used in ScInterpreter::IterateParameterIfs(). Store this
cache as a member of ScInterpreterContext (maConditions).
Create a static pool of ScInterpreterContext's so that
the embedded maConditions is reused everytime a formula-group/
formula-cell is calculated. There needs to be two separate
static pools - one for threading, one for non-threaded
computation of formula-cells. With this, we can have better
performance of the cached maConditions as well as
mScLookupCache. In threaded case there is no recursive
computation of cells as dependencies are all pre-computed.
The thread-indexed lookup cache array in ScDocument is
removed as now the lookup caches on context lives as long
in the static context pools.
This cached vConditions array can take advantage
when there are lots of SUMIFS/COUNTIFS with arguments of
similar dimensions in the document. Otherwise it will be
allocated from scratch for every COUNTIFS/SUMIFS formula-cell.
Change-Id: I654b05e55035ce6efcf07d32d36623c9d76b0ff6
Reviewed-on: https://gerrit.libreoffice.org/63066
Tested-by: Jenkins
Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
Diffstat (limited to 'sc/inc/interpretercontext.hxx')
-rw-r--r-- | sc/inc/interpretercontext.hxx | 95 |
1 files changed, 93 insertions, 2 deletions
diff --git a/sc/inc/interpretercontext.hxx b/sc/inc/interpretercontext.hxx index b12bf17410a4..2b690e311b8c 100644 --- a/sc/inc/interpretercontext.hxx +++ b/sc/inc/interpretercontext.hxx @@ -11,6 +11,7 @@ #define INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX #include <vector> +#include <memory> #include "types.hxx" namespace formula @@ -31,17 +32,22 @@ struct DelayedSetNumberFormat sal_uInt32 mnNumberFormat; }; +class ScInterpreterContextPool; + struct ScInterpreterContext { - const ScDocument& mrDoc; + const ScDocument* mpDoc; SvNumberFormatter* mpFormatter; size_t mnTokenCachePos; std::vector<formula::FormulaToken*> maTokens; std::vector<DelayedSetNumberFormat> maDelayedSetNumberFormat; ScLookupCacheMap* mScLookupCache; // cache for lookups like VLOOKUP and MATCH + // Allocation cache for "aConditions" array in ScInterpreter::IterateParameterIfs() + // This is populated/used only when formula-group threading is enabled. + std::vector<sal_uInt32> maConditions; ScInterpreterContext(const ScDocument& rDoc, SvNumberFormatter* pFormatter) - : mrDoc(rDoc) + : mpDoc(&rDoc) , mpFormatter(pFormatter) , mnTokenCachePos(0) , maTokens(TOKEN_CACHE_SIZE, nullptr) @@ -49,9 +55,94 @@ struct ScInterpreterContext { } + ScInterpreterContext() = delete; + ~ScInterpreterContext(); SvNumberFormatter* GetFormatTable() const { return mpFormatter; } + +private: + friend class ScInterpreterContextPool; + void ResetTokens(); + void SetDocAndFormatter(const ScDocument& rDoc, SvNumberFormatter* pFormatter); + void Cleanup(); + void ClearLookupCache(); +}; + +class ScThreadedInterpreterContextGetterGuard; +class ScInterpreterContextGetterGuard; + +class ScInterpreterContextPool +{ + friend class ScThreadedInterpreterContextGetterGuard; + friend class ScInterpreterContextGetterGuard; + + std::vector<std::unique_ptr<ScInterpreterContext>> maPool; + size_t mnNextFree; + bool mbThreaded; + + ScInterpreterContextPool(bool bThreaded) + : mnNextFree(0) + , mbThreaded(bThreaded) + { + } + + ~ScInterpreterContextPool() {} + + static ScInterpreterContextPool aThreadedInterpreterPool; + static ScInterpreterContextPool aNonThreadedInterpreterPool; + + // API for threaded case + + // Ensures nNumThreads elements in pool. + void Init(size_t nNumThreads, const ScDocument& rDoc, SvNumberFormatter* pFormatter); + + // Returns ScInterpreterContext* for thread index nThreadIdx + ScInterpreterContext* GetInterpreterContextForThreadIdx(size_t nThreadIdx) const; + + // API for non-threaded + + // Ensures there is one unused element in the pool. + void Init(const ScDocument& rDoc, SvNumberFormatter* pFormatter); + + // Returns ScInterpreterContext* for non-threaded use. + ScInterpreterContext* GetInterpreterContext() const; + + // Common API for threaded/non-threaded + + // Cleans up the contexts prepared by call to immediately previous Init() and + // marks them all as unused. + void ReturnToPool(); + +public: + // Only to be used to clear lookup cache in all pool elements + static void ClearLookupCaches(); +}; + +class ScThreadedInterpreterContextGetterGuard +{ + ScInterpreterContextPool& rPool; + +public: + ScThreadedInterpreterContextGetterGuard(size_t nNumThreads, const ScDocument& rDoc, + SvNumberFormatter* pFormatter); + ~ScThreadedInterpreterContextGetterGuard(); + + // Returns ScInterpreterContext* for thread index nThreadIdx + ScInterpreterContext* GetInterpreterContextForThreadIdx(size_t nThreadIdx) const; +}; + +class ScInterpreterContextGetterGuard +{ + ScInterpreterContextPool& rPool; + size_t nContextIdx; + +public: + ScInterpreterContextGetterGuard(const ScDocument& rDoc, SvNumberFormatter* pFormatter); + ~ScInterpreterContextGetterGuard(); + + // Returns ScInterpreterContext* for non-threaded use. + ScInterpreterContext* GetInterpreterContext() const; }; #endif // INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX |