diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2011-04-29 12:26:16 -0400 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2011-04-29 12:28:08 -0400 |
commit | 08ad6f55a7bc29b865756fe8f328b61628355519 (patch) | |
tree | 63a3d3a0cb5c5757c281bffc877eb6b3681395c0 | |
parent | 85e269f9cd7afa5633c2222acc6179dfffdf8577 (diff) |
Manage data caches for named range data source separately.
Without this, updating the named range and refreshing would fail to
remove the old cache, which is no longer referenced. Very bad for
memory footprint.
-rw-r--r-- | sc/inc/dpobject.hxx | 16 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 30 | ||||
-rw-r--r-- | sc/source/core/data/dpshttab.cxx | 7 | ||||
-rw-r--r-- | sc/source/ui/view/dbfunc3.cxx | 24 |
4 files changed, 74 insertions, 3 deletions
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 9972e0c1198f..30ca8406d11e 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -274,6 +274,20 @@ public: }; /** + * Data caches for range name based source data. + */ + class NameCaches + { + typedef ::boost::ptr_map<rtl::OUString, ScDPCache> CachesType; + CachesType maCaches; + ScDocument* mpDoc; + public: + NameCaches(ScDocument* pDoc); + const ScDPCache* getCache(const ::rtl::OUString& rName, const ScRange& rRange); + void removeCache(const ::rtl::OUString& rName); + }; + + /** * Defines connection type to external data source. Used as a key to look * up database cache. */ @@ -333,6 +347,7 @@ public: bool HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const; SheetCaches& GetSheetCaches(); + NameCaches& GetNameCaches(); DBCaches& GetDBCaches(); private: @@ -341,6 +356,7 @@ private: ScDocument* pDoc; TablesType maTables; SheetCaches maSheetCaches; + NameCaches maNameCaches; DBCaches maDBCaches; }; diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index e8d6a2334b23..fcd4a75aed87 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -2416,6 +2416,29 @@ void ScDPCollection::SheetCaches::removeCache(const ScRange& rRange) maCaches.erase(itr); } +ScDPCollection::NameCaches::NameCaches(ScDocument* pDoc) : mpDoc(pDoc) {} + +const ScDPCache* ScDPCollection::NameCaches::getCache(const OUString& rName, const ScRange& rRange) +{ + CachesType::const_iterator itr = maCaches.find(rName); + if (itr != maCaches.end()) + // already cached. + return itr->second; + + ::std::auto_ptr<ScDPCache> pCache(new ScDPCache(mpDoc)); + pCache->InitFromDoc(mpDoc, rRange); + const ScDPCache* p = pCache.get(); + maCaches.insert(rName, pCache); + return p; +} + +void ScDPCollection::NameCaches::removeCache(const OUString& rName) +{ + CachesType::iterator itr = maCaches.find(rName); + if (itr != maCaches.end()) + maCaches.erase(itr); +} + ScDPCollection::DBType::DBType(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) : mnSdbType(nSdbType), maDBName(rDBName), maCommand(rCommand) {} @@ -2502,6 +2525,7 @@ void ScDPCollection::DBCaches::removeCache(sal_Int32 nSdbType, const OUString& r ScDPCollection::ScDPCollection(ScDocument* pDocument) : pDoc( pDocument ), maSheetCaches(pDocument), + maNameCaches(pDocument), maDBCaches(pDocument) { } @@ -2509,6 +2533,7 @@ ScDPCollection::ScDPCollection(ScDocument* pDocument) : ScDPCollection::ScDPCollection(const ScDPCollection& r) : pDoc(r.pDoc), maSheetCaches(r.pDoc), + maNameCaches(r.pDoc), maDBCaches(r.pDoc) { } @@ -2707,6 +2732,11 @@ ScDPCollection::SheetCaches& ScDPCollection::GetSheetCaches() return maSheetCaches; } +ScDPCollection::NameCaches& ScDPCollection::GetNameCaches() +{ + return maNameCaches; +} + ScDPCollection::DBCaches& ScDPCollection::GetDBCaches() { return maDBCaches; diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx index c05d333f5ba6..cfad761377bc 100644 --- a/sc/source/core/data/dpshttab.cxx +++ b/sc/source/core/data/dpshttab.cxx @@ -321,6 +321,13 @@ const ScDPCache* ScSheetSourceDesc::CreateCache() const // All cache instances are managed centrally by ScDPCollection. ScDPCollection* pDPs = mpDoc->GetDPCollection(); + if (HasRangeName()) + { + // Name-based data source. + ScDPCollection::NameCaches& rCaches = pDPs->GetNameCaches(); + return rCaches.getCache(GetRangeName(), GetSourceRange()); + } + ScDPCollection::SheetCaches& rCaches = pDPs->GetSheetCaches(); return rCaches.getCache(GetSourceRange()); } diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 3ce6b978f1be..e8e5baafb1f7 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -710,15 +710,33 @@ void ScDBFunc::RecalcPivotTable() if (pDPObj->IsSheetData()) { // data source is internal sheet. - ScDPCollection::SheetCaches& rCaches = pDPs->GetSheetCaches(); const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc(); - rCaches.removeCache(pDesc->GetSourceRange()); + if (!pDesc) + { + ErrorMessage(STR_PIVOT_NOTFOUND); + return; + } + if (pDesc->HasRangeName()) + { + ScDPCollection::NameCaches& rCaches = pDPs->GetNameCaches(); + rCaches.removeCache(pDesc->GetRangeName()); + } + else + { + ScDPCollection::SheetCaches& rCaches = pDPs->GetSheetCaches(); + rCaches.removeCache(pDesc->GetSourceRange()); + } } else if (pDPObj->IsImportData()) { // data source is external database. - ScDPCollection::DBCaches& rCaches = pDPs->GetDBCaches(); const ScImportSourceDesc* pDesc = pDPObj->GetImportSourceDesc(); + if (!pDesc) + { + ErrorMessage(STR_PIVOT_NOTFOUND); + return; + } + ScDPCollection::DBCaches& rCaches = pDPs->GetDBCaches(); rCaches.removeCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject); } |