xref: /trunk/main/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*5b190011SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*5b190011SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*5b190011SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*5b190011SAndrew Rist  * distributed with this work for additional information
6*5b190011SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*5b190011SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*5b190011SAndrew Rist  * "License"); you may not use this file except in compliance
9*5b190011SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*5b190011SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*5b190011SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*5b190011SAndrew Rist  * software distributed under the License is distributed on an
15*5b190011SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*5b190011SAndrew Rist  * KIND, either express or implied.  See the License for the
17*5b190011SAndrew Rist  * specific language governing permissions and limitations
18*5b190011SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*5b190011SAndrew Rist  *************************************************************/
21*5b190011SAndrew Rist 
22*5b190011SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sd.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "cache/SlsPageCacheManager.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "SlsBitmapCache.hxx"
30cdf0e10cSrcweir #include "view/SlideSorterView.hxx"
31cdf0e10cSrcweir #include "model/SlideSorterModel.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <deque>
34cdf0e10cSrcweir #include <map>
35cdf0e10cSrcweir #include <boost/weak_ptr.hpp>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir namespace {
38cdf0e10cSrcweir 
39cdf0e10cSrcweir /** Collection of data that is stored for all active preview caches.
40cdf0e10cSrcweir */
41cdf0e10cSrcweir class CacheDescriptor
42cdf0e10cSrcweir {
43cdf0e10cSrcweir public:
44cdf0e10cSrcweir     ::sd::slidesorter::cache::PageCacheManager::DocumentKey mpDocument;
45cdf0e10cSrcweir     Size maPreviewSize;
46cdf0e10cSrcweir 
CacheDescriptor(::sd::slidesorter::cache::PageCacheManager::DocumentKey pDocument,const Size & rPreviewSize)47cdf0e10cSrcweir     CacheDescriptor(
48cdf0e10cSrcweir         ::sd::slidesorter::cache::PageCacheManager::DocumentKey pDocument,
49cdf0e10cSrcweir         const Size& rPreviewSize)
50cdf0e10cSrcweir         :mpDocument(pDocument),maPreviewSize(rPreviewSize)
51cdf0e10cSrcweir     {}
52cdf0e10cSrcweir     /// Test for equality with respect to all members.
operator ()(const CacheDescriptor & rDescriptor1,const CacheDescriptor & rDescriptor2) const53cdf0e10cSrcweir     class Equal {public: bool operator() (
54cdf0e10cSrcweir         const CacheDescriptor& rDescriptor1, const CacheDescriptor& rDescriptor2) const {
55cdf0e10cSrcweir         return rDescriptor1.mpDocument==rDescriptor2.mpDocument
56cdf0e10cSrcweir             && rDescriptor1.maPreviewSize==rDescriptor2.maPreviewSize;
57cdf0e10cSrcweir     } };
58cdf0e10cSrcweir     /// Hash function that takes all members into account.
operator ()(const CacheDescriptor & rDescriptor) const59cdf0e10cSrcweir     class Hash {public: size_t operator() (const CacheDescriptor& rDescriptor) const {
60cdf0e10cSrcweir         return (size_t)rDescriptor.mpDocument.get() + rDescriptor.maPreviewSize.Width();
61cdf0e10cSrcweir     } };
62cdf0e10cSrcweir };
63cdf0e10cSrcweir 
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 
67cdf0e10cSrcweir /** Collection of data that is stored for the inactive, recently used
68cdf0e10cSrcweir     caches.
69cdf0e10cSrcweir */
70cdf0e10cSrcweir class RecentlyUsedCacheDescriptor
71cdf0e10cSrcweir {
72cdf0e10cSrcweir public:
73cdf0e10cSrcweir     ::sd::slidesorter::cache::PageCacheManager::DocumentKey mpDocument;
74cdf0e10cSrcweir     Size maPreviewSize;
75cdf0e10cSrcweir     ::boost::shared_ptr< ::sd::slidesorter::cache::PageCacheManager::Cache> mpCache;
76cdf0e10cSrcweir 
RecentlyUsedCacheDescriptor(::sd::slidesorter::cache::PageCacheManager::DocumentKey pDocument,const Size & rPreviewSize,const::boost::shared_ptr<::sd::slidesorter::cache::PageCacheManager::Cache> & rpCache)77cdf0e10cSrcweir     RecentlyUsedCacheDescriptor(
78cdf0e10cSrcweir         ::sd::slidesorter::cache::PageCacheManager::DocumentKey pDocument,
79cdf0e10cSrcweir         const Size& rPreviewSize,
80cdf0e10cSrcweir         const ::boost::shared_ptr< ::sd::slidesorter::cache::PageCacheManager::Cache>& rpCache)
81cdf0e10cSrcweir         :mpDocument(pDocument),maPreviewSize(rPreviewSize),mpCache(rpCache)
82cdf0e10cSrcweir     {}
83cdf0e10cSrcweir };
84cdf0e10cSrcweir 
85cdf0e10cSrcweir 
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 
88cdf0e10cSrcweir /** The list of recently used caches is organized as queue.  When elements
89cdf0e10cSrcweir     are added the list is shortened to the maximally allowed number of
90cdf0e10cSrcweir     elements by removing the least recently used elements.
91cdf0e10cSrcweir */
92cdf0e10cSrcweir typedef ::std::deque<RecentlyUsedCacheDescriptor> RecentlyUsedQueue;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 
97cdf0e10cSrcweir /** Compare the caches by preview size.  Those that match the given size
98cdf0e10cSrcweir     come first, then, regardless of the given size, the largest ones before
99cdf0e10cSrcweir     the smaller ones.
100cdf0e10cSrcweir */
101cdf0e10cSrcweir class BestFittingCacheComparer
102cdf0e10cSrcweir {
103cdf0e10cSrcweir public:
BestFittingCacheComparer(const Size & rPreferredSize)104cdf0e10cSrcweir     BestFittingCacheComparer (const Size& rPreferredSize)
105cdf0e10cSrcweir         : maPreferredSize(rPreferredSize)
106cdf0e10cSrcweir     {}
operator ()(const::sd::slidesorter::cache::PageCacheManager::BestFittingPageCaches::value_type & rElement1,const::sd::slidesorter::cache::PageCacheManager::BestFittingPageCaches::value_type & rElement2)107cdf0e10cSrcweir     bool operator()(const ::sd::slidesorter::cache::PageCacheManager::BestFittingPageCaches::value_type& rElement1,
108cdf0e10cSrcweir         const ::sd::slidesorter::cache::PageCacheManager::BestFittingPageCaches::value_type& rElement2)
109cdf0e10cSrcweir     {
110cdf0e10cSrcweir         if (rElement1.first == maPreferredSize)
111cdf0e10cSrcweir             return true;
112cdf0e10cSrcweir         else if (rElement2.first == maPreferredSize)
113cdf0e10cSrcweir             return false;
114cdf0e10cSrcweir         else
115cdf0e10cSrcweir             return (rElement1.first.Width()*rElement1.first.Height()
116cdf0e10cSrcweir                 > rElement2.first.Width()*rElement2.first.Height());
117cdf0e10cSrcweir     }
118cdf0e10cSrcweir 
119cdf0e10cSrcweir private:
120cdf0e10cSrcweir     Size maPreferredSize;
121cdf0e10cSrcweir };
122cdf0e10cSrcweir 
123cdf0e10cSrcweir } // end of anonymous namespace
124cdf0e10cSrcweir 
125cdf0e10cSrcweir 
126cdf0e10cSrcweir namespace sd { namespace slidesorter { namespace cache {
127cdf0e10cSrcweir 
128cdf0e10cSrcweir /** Container for the active caches.
129cdf0e10cSrcweir */
130cdf0e10cSrcweir class PageCacheManager::PageCacheContainer
131cdf0e10cSrcweir     : public ::std::hash_map<CacheDescriptor,
132cdf0e10cSrcweir                              ::boost::shared_ptr<PageCacheManager::Cache>,
133cdf0e10cSrcweir                              CacheDescriptor::Hash,
134cdf0e10cSrcweir                              CacheDescriptor::Equal>
135cdf0e10cSrcweir {
136cdf0e10cSrcweir public:
PageCacheContainer(void)137cdf0e10cSrcweir     PageCacheContainer (void) {}
138cdf0e10cSrcweir 
139cdf0e10cSrcweir     /** Compare entries in the cache container with respect to the cache
140cdf0e10cSrcweir         address only.
141cdf0e10cSrcweir     */
142cdf0e10cSrcweir     class CompareWithCache { public:
CompareWithCache(const::boost::shared_ptr<PageCacheManager::Cache> & rpCache)143cdf0e10cSrcweir         CompareWithCache(const ::boost::shared_ptr<PageCacheManager::Cache>& rpCache)
144cdf0e10cSrcweir             : mpCache(rpCache) {}
operator ()(const PageCacheContainer::value_type & rValue)145cdf0e10cSrcweir         bool operator () (const PageCacheContainer::value_type& rValue)
146cdf0e10cSrcweir         { return rValue.second == mpCache; }
147cdf0e10cSrcweir     private:
148cdf0e10cSrcweir         ::boost::shared_ptr<PageCacheManager::Cache> mpCache;
149cdf0e10cSrcweir     };
150cdf0e10cSrcweir };
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 
153cdf0e10cSrcweir /** The recently used caches are stored in one queue for each document.
154cdf0e10cSrcweir */
155cdf0e10cSrcweir class PageCacheManager::RecentlyUsedPageCaches
156cdf0e10cSrcweir     : public ::std::map<DocumentKey,RecentlyUsedQueue>
157cdf0e10cSrcweir {
158cdf0e10cSrcweir public:
RecentlyUsedPageCaches(void)159cdf0e10cSrcweir     RecentlyUsedPageCaches (void) {};
160cdf0e10cSrcweir };
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 
165cdf0e10cSrcweir class PageCacheManager::Deleter
166cdf0e10cSrcweir {
167cdf0e10cSrcweir public:
operator ()(PageCacheManager * pObject)168cdf0e10cSrcweir     void operator() (PageCacheManager* pObject) { delete pObject; }
169cdf0e10cSrcweir };
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 
173cdf0e10cSrcweir //===== PageCacheManager ====================================================
174cdf0e10cSrcweir 
175cdf0e10cSrcweir ::boost::weak_ptr<PageCacheManager> PageCacheManager::mpInstance;
176cdf0e10cSrcweir 
Instance(void)177cdf0e10cSrcweir ::boost::shared_ptr<PageCacheManager> PageCacheManager::Instance (void)
178cdf0e10cSrcweir {
179cdf0e10cSrcweir     ::boost::shared_ptr<PageCacheManager> pInstance;
180cdf0e10cSrcweir 
181cdf0e10cSrcweir     ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     pInstance = mpInstance.lock();
184cdf0e10cSrcweir     if (pInstance.get() == NULL)
185cdf0e10cSrcweir     {
186cdf0e10cSrcweir         pInstance = ::boost::shared_ptr<PageCacheManager>(
187cdf0e10cSrcweir             new PageCacheManager(),
188cdf0e10cSrcweir             PageCacheManager::Deleter());
189cdf0e10cSrcweir         mpInstance = pInstance;
190cdf0e10cSrcweir     }
191cdf0e10cSrcweir 
192cdf0e10cSrcweir     return pInstance;
193cdf0e10cSrcweir }
194cdf0e10cSrcweir 
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 
PageCacheManager(void)198cdf0e10cSrcweir PageCacheManager::PageCacheManager (void)
199cdf0e10cSrcweir     : mpPageCaches(new PageCacheContainer()),
200cdf0e10cSrcweir       mpRecentlyUsedPageCaches(new RecentlyUsedPageCaches()),
201cdf0e10cSrcweir       mnMaximalRecentlyCacheCount(2)
202cdf0e10cSrcweir {
203cdf0e10cSrcweir }
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 
206cdf0e10cSrcweir 
207cdf0e10cSrcweir 
~PageCacheManager(void)208cdf0e10cSrcweir PageCacheManager::~PageCacheManager (void)
209cdf0e10cSrcweir {
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 
GetCache(DocumentKey pDocument,const Size & rPreviewSize)215cdf0e10cSrcweir ::boost::shared_ptr<PageCacheManager::Cache> PageCacheManager::GetCache (
216cdf0e10cSrcweir     DocumentKey pDocument,
217cdf0e10cSrcweir     const Size& rPreviewSize)
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     ::boost::shared_ptr<Cache> pResult;
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     // Look for the cache in the list of active caches.
222cdf0e10cSrcweir     CacheDescriptor aKey (pDocument, rPreviewSize);
223cdf0e10cSrcweir     PageCacheContainer::iterator iCache (mpPageCaches->find(aKey));
224cdf0e10cSrcweir     if (iCache != mpPageCaches->end())
225cdf0e10cSrcweir         pResult = iCache->second;
226cdf0e10cSrcweir 
227cdf0e10cSrcweir     // Look for the cache in the list of recently used caches.
228cdf0e10cSrcweir     if (pResult.get() == NULL)
229cdf0e10cSrcweir         pResult = GetRecentlyUsedCache(pDocument, rPreviewSize);
230cdf0e10cSrcweir 
231cdf0e10cSrcweir     // Create the cache when no suitable one does exist.
232cdf0e10cSrcweir     if (pResult.get() == NULL)
233cdf0e10cSrcweir         pResult.reset(new Cache());
234cdf0e10cSrcweir 
235cdf0e10cSrcweir     // The cache may be newly created and thus empty or is old and may
236cdf0e10cSrcweir     // contain previews that are not up-to-date.  Recycle previews from
237cdf0e10cSrcweir     // other caches to fill in the holes.
238cdf0e10cSrcweir     Recycle(pResult, pDocument,rPreviewSize);
239cdf0e10cSrcweir 
240cdf0e10cSrcweir     // Put the new (or old) cache into the container.
241cdf0e10cSrcweir     if (pResult.get() != NULL)
242cdf0e10cSrcweir         mpPageCaches->insert(PageCacheContainer::value_type(aKey, pResult));
243cdf0e10cSrcweir 
244cdf0e10cSrcweir     return pResult;
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 
Recycle(const::boost::shared_ptr<Cache> & rpCache,DocumentKey pDocument,const Size & rPreviewSize)250cdf0e10cSrcweir void PageCacheManager::Recycle (
251cdf0e10cSrcweir     const ::boost::shared_ptr<Cache>& rpCache,
252cdf0e10cSrcweir     DocumentKey pDocument,
253cdf0e10cSrcweir     const Size& rPreviewSize)
254cdf0e10cSrcweir {
255cdf0e10cSrcweir     BestFittingPageCaches aCaches;
256cdf0e10cSrcweir 
257cdf0e10cSrcweir     // Add bitmap caches from active caches.
258cdf0e10cSrcweir     PageCacheContainer::iterator iActiveCache;
259cdf0e10cSrcweir     for (iActiveCache=mpPageCaches->begin(); iActiveCache!=mpPageCaches->end(); ++iActiveCache)
260cdf0e10cSrcweir     {
261cdf0e10cSrcweir         if (iActiveCache->first.mpDocument == pDocument)
262cdf0e10cSrcweir             aCaches.push_back(BestFittingPageCaches::value_type(
263cdf0e10cSrcweir                 iActiveCache->first.maPreviewSize, iActiveCache->second));
264cdf0e10cSrcweir     }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     // Add bitmap caches from recently used caches.
267cdf0e10cSrcweir     RecentlyUsedPageCaches::iterator iQueue (mpRecentlyUsedPageCaches->find(pDocument));
268cdf0e10cSrcweir     if (iQueue != mpRecentlyUsedPageCaches->end())
269cdf0e10cSrcweir     {
270cdf0e10cSrcweir         RecentlyUsedQueue::const_iterator iRecentCache;
271cdf0e10cSrcweir         for (iRecentCache=iQueue->second.begin();iRecentCache!=iQueue->second.end();++iRecentCache)
272cdf0e10cSrcweir             aCaches.push_back(BestFittingPageCaches::value_type(
273cdf0e10cSrcweir                 iRecentCache->maPreviewSize, iRecentCache->mpCache));
274cdf0e10cSrcweir     }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir     ::std::sort(aCaches.begin(), aCaches.end(), BestFittingCacheComparer(rPreviewSize));
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     BestFittingPageCaches::const_iterator iBestCache;
279cdf0e10cSrcweir     for (iBestCache=aCaches.begin(); iBestCache!=aCaches.end(); ++iBestCache)
280cdf0e10cSrcweir     {
281cdf0e10cSrcweir         rpCache->Recycle(*iBestCache->second);
282cdf0e10cSrcweir     }
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 
ReleaseCache(const::boost::shared_ptr<Cache> & rpCache)288cdf0e10cSrcweir void PageCacheManager::ReleaseCache (const ::boost::shared_ptr<Cache>& rpCache)
289cdf0e10cSrcweir {
290cdf0e10cSrcweir     PageCacheContainer::iterator iCache (::std::find_if(
291cdf0e10cSrcweir         mpPageCaches->begin(),
292cdf0e10cSrcweir         mpPageCaches->end(),
293cdf0e10cSrcweir         PageCacheContainer::CompareWithCache(rpCache)));
294cdf0e10cSrcweir 
295cdf0e10cSrcweir     if (iCache != mpPageCaches->end())
296cdf0e10cSrcweir     {
297cdf0e10cSrcweir         OSL_ASSERT(iCache->second == rpCache);
298cdf0e10cSrcweir 
299cdf0e10cSrcweir         PutRecentlyUsedCache(iCache->first.mpDocument,iCache->first.maPreviewSize,rpCache);
300cdf0e10cSrcweir 
301cdf0e10cSrcweir         mpPageCaches->erase(iCache);
302cdf0e10cSrcweir     }
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 
ChangeSize(const::boost::shared_ptr<Cache> & rpCache,const Size & rOldPreviewSize,const Size & rNewPreviewSize)308cdf0e10cSrcweir ::boost::shared_ptr<PageCacheManager::Cache> PageCacheManager::ChangeSize (
309cdf0e10cSrcweir     const ::boost::shared_ptr<Cache>& rpCache,
310cdf0e10cSrcweir     const Size& rOldPreviewSize,
311cdf0e10cSrcweir     const Size& rNewPreviewSize)
312cdf0e10cSrcweir {
313cdf0e10cSrcweir     (void)rOldPreviewSize;
314cdf0e10cSrcweir 
315cdf0e10cSrcweir     ::boost::shared_ptr<Cache> pResult;
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     if (rpCache.get() != NULL)
318cdf0e10cSrcweir     {
319cdf0e10cSrcweir         // Look up the given cache in the list of active caches.
320cdf0e10cSrcweir         PageCacheContainer::iterator iCacheToChange (::std::find_if(
321cdf0e10cSrcweir             mpPageCaches->begin(),
322cdf0e10cSrcweir             mpPageCaches->end(),
323cdf0e10cSrcweir             PageCacheContainer::CompareWithCache(rpCache)));
324cdf0e10cSrcweir         if (iCacheToChange != mpPageCaches->end())
325cdf0e10cSrcweir         {
326cdf0e10cSrcweir             OSL_ASSERT(iCacheToChange->second == rpCache);
327cdf0e10cSrcweir 
328cdf0e10cSrcweir             // Now, we can change the preview size of the existing one by
329cdf0e10cSrcweir             // removing the cache from the list and re-insert it with the
330cdf0e10cSrcweir             // updated size.
331cdf0e10cSrcweir             const ::sd::slidesorter::cache::PageCacheManager::DocumentKey aKey (
332cdf0e10cSrcweir                 iCacheToChange->first.mpDocument);
333cdf0e10cSrcweir             mpPageCaches->erase(iCacheToChange);
334cdf0e10cSrcweir             mpPageCaches->insert(PageCacheContainer::value_type(
335cdf0e10cSrcweir                 CacheDescriptor(aKey,rNewPreviewSize),
336cdf0e10cSrcweir                 rpCache));
337cdf0e10cSrcweir 
338cdf0e10cSrcweir             pResult = rpCache;
339cdf0e10cSrcweir         }
340cdf0e10cSrcweir         else
341cdf0e10cSrcweir         {
342cdf0e10cSrcweir             OSL_ASSERT(iCacheToChange != mpPageCaches->end());
343cdf0e10cSrcweir         }
344cdf0e10cSrcweir     }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir     return pResult;
347cdf0e10cSrcweir }
348cdf0e10cSrcweir 
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 
InvalidatePreviewBitmap(DocumentKey pDocument,const SdrPage * pKey)352cdf0e10cSrcweir bool PageCacheManager::InvalidatePreviewBitmap (
353cdf0e10cSrcweir     DocumentKey pDocument,
354cdf0e10cSrcweir     const SdrPage* pKey)
355cdf0e10cSrcweir {
356cdf0e10cSrcweir     bool bHasChanged (false);
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     if (pDocument!=NULL)
359cdf0e10cSrcweir     {
360cdf0e10cSrcweir         // Iterate over all caches that are currently in use and invalidate
361cdf0e10cSrcweir         // the previews in those that belong to the document.
362cdf0e10cSrcweir         PageCacheContainer::iterator iCache;
363cdf0e10cSrcweir         for (iCache=mpPageCaches->begin(); iCache!=mpPageCaches->end();  ++iCache)
364cdf0e10cSrcweir             if (iCache->first.mpDocument == pDocument)
365cdf0e10cSrcweir                 bHasChanged |= iCache->second->InvalidateBitmap(pKey);
366cdf0e10cSrcweir 
367cdf0e10cSrcweir         // Invalidate the previews in the recently used caches belonging to
368cdf0e10cSrcweir         // the given document.
369cdf0e10cSrcweir         RecentlyUsedPageCaches::iterator iQueue (mpRecentlyUsedPageCaches->find(pDocument));
370cdf0e10cSrcweir         if (iQueue != mpRecentlyUsedPageCaches->end())
371cdf0e10cSrcweir         {
372cdf0e10cSrcweir             RecentlyUsedQueue::const_iterator iCache2;
373cdf0e10cSrcweir             for (iCache2=iQueue->second.begin(); iCache2!=iQueue->second.end(); ++iCache2)
374cdf0e10cSrcweir                 bHasChanged |= iCache2->mpCache->InvalidateBitmap(pKey);
375cdf0e10cSrcweir         }
376cdf0e10cSrcweir     }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     return bHasChanged;
379cdf0e10cSrcweir }
380cdf0e10cSrcweir 
381cdf0e10cSrcweir 
382cdf0e10cSrcweir 
383cdf0e10cSrcweir 
InvalidateAllPreviewBitmaps(DocumentKey pDocument)384cdf0e10cSrcweir void PageCacheManager::InvalidateAllPreviewBitmaps (DocumentKey pDocument)
385cdf0e10cSrcweir {
386cdf0e10cSrcweir     if (pDocument == NULL)
387cdf0e10cSrcweir         return;
388cdf0e10cSrcweir 
389cdf0e10cSrcweir     // Iterate over all caches that are currently in use and invalidate the
390cdf0e10cSrcweir     // previews in those that belong to the document.
391cdf0e10cSrcweir     PageCacheContainer::iterator iCache;
392cdf0e10cSrcweir     for (iCache=mpPageCaches->begin(); iCache!=mpPageCaches->end();  ++iCache)
393cdf0e10cSrcweir         if (iCache->first.mpDocument == pDocument)
394cdf0e10cSrcweir             iCache->second->InvalidateCache();
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     // Invalidate the previews in the recently used caches belonging to the
397cdf0e10cSrcweir     // given document.
398cdf0e10cSrcweir     RecentlyUsedPageCaches::iterator iQueue (mpRecentlyUsedPageCaches->find(pDocument));
399cdf0e10cSrcweir     if (iQueue != mpRecentlyUsedPageCaches->end())
400cdf0e10cSrcweir     {
401cdf0e10cSrcweir         RecentlyUsedQueue::const_iterator iCache2;
402cdf0e10cSrcweir         for (iCache2=iQueue->second.begin(); iCache2!=iQueue->second.end(); ++iCache2)
403cdf0e10cSrcweir             iCache2->mpCache->InvalidateCache();
404cdf0e10cSrcweir     }
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 
InvalidateAllCaches(void)410cdf0e10cSrcweir void PageCacheManager::InvalidateAllCaches (void)
411cdf0e10cSrcweir {
412cdf0e10cSrcweir     // Iterate over all caches that are currently in use and invalidate
413cdf0e10cSrcweir     // them.
414cdf0e10cSrcweir     PageCacheContainer::iterator iCache;
415cdf0e10cSrcweir     for (iCache=mpPageCaches->begin(); iCache!=mpPageCaches->end();  ++iCache)
416cdf0e10cSrcweir         iCache->second->InvalidateCache();
417cdf0e10cSrcweir 
418cdf0e10cSrcweir     // Remove all recently used caches, there is not much sense in storing
419cdf0e10cSrcweir     // invalidated and unused caches.
420cdf0e10cSrcweir     mpRecentlyUsedPageCaches->clear();
421cdf0e10cSrcweir }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 
424cdf0e10cSrcweir 
425cdf0e10cSrcweir 
ReleasePreviewBitmap(const SdrPage * pPage)426cdf0e10cSrcweir void PageCacheManager::ReleasePreviewBitmap (const SdrPage* pPage)
427cdf0e10cSrcweir {
428cdf0e10cSrcweir     PageCacheContainer::iterator iCache;
429cdf0e10cSrcweir     for (iCache=mpPageCaches->begin(); iCache!=mpPageCaches->end(); ++iCache)
430cdf0e10cSrcweir         iCache->second->ReleaseBitmap(pPage);
431cdf0e10cSrcweir }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 
435cdf0e10cSrcweir 
GetRecentlyUsedCache(DocumentKey pDocument,const Size & rPreviewSize)436cdf0e10cSrcweir ::boost::shared_ptr<PageCacheManager::Cache> PageCacheManager::GetRecentlyUsedCache (
437cdf0e10cSrcweir     DocumentKey pDocument,
438cdf0e10cSrcweir     const Size& rPreviewSize)
439cdf0e10cSrcweir {
440cdf0e10cSrcweir     ::boost::shared_ptr<Cache> pCache;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir     // Look for the cache in the list of recently used caches.
443cdf0e10cSrcweir     RecentlyUsedPageCaches::iterator iQueue (mpRecentlyUsedPageCaches->find(pDocument));
444cdf0e10cSrcweir     if (iQueue != mpRecentlyUsedPageCaches->end())
445cdf0e10cSrcweir     {
446cdf0e10cSrcweir         RecentlyUsedQueue::iterator iCache;
447cdf0e10cSrcweir         for (iCache=iQueue->second.begin(); iCache!= iQueue->second.end(); ++iCache)
448cdf0e10cSrcweir             if (iCache->maPreviewSize == rPreviewSize)
449cdf0e10cSrcweir             {
450cdf0e10cSrcweir                 pCache = iCache->mpCache;
451cdf0e10cSrcweir                 iQueue->second.erase(iCache);
452cdf0e10cSrcweir                 break;
453cdf0e10cSrcweir             }
454cdf0e10cSrcweir     }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir     return pCache;
457cdf0e10cSrcweir }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 
PutRecentlyUsedCache(DocumentKey pDocument,const Size & rPreviewSize,const::boost::shared_ptr<Cache> & rpCache)462cdf0e10cSrcweir void PageCacheManager::PutRecentlyUsedCache(
463cdf0e10cSrcweir     DocumentKey pDocument,
464cdf0e10cSrcweir     const Size& rPreviewSize,
465cdf0e10cSrcweir     const ::boost::shared_ptr<Cache>& rpCache)
466cdf0e10cSrcweir {
467cdf0e10cSrcweir     // Look up the list of recently used caches for the given document.
468cdf0e10cSrcweir     RecentlyUsedPageCaches::iterator iQueue (mpRecentlyUsedPageCaches->find(pDocument));
469cdf0e10cSrcweir     if (iQueue == mpRecentlyUsedPageCaches->end())
470cdf0e10cSrcweir         iQueue = mpRecentlyUsedPageCaches->insert(
471cdf0e10cSrcweir             RecentlyUsedPageCaches::value_type(pDocument, RecentlyUsedQueue())
472cdf0e10cSrcweir             ).first;
473cdf0e10cSrcweir 
474cdf0e10cSrcweir     if (iQueue != mpRecentlyUsedPageCaches->end())
475cdf0e10cSrcweir     {
476cdf0e10cSrcweir         iQueue->second.push_front(RecentlyUsedCacheDescriptor(pDocument,rPreviewSize,rpCache));
477cdf0e10cSrcweir         // Shorten the list of recently used caches to the allowed maximal length.
478cdf0e10cSrcweir         while (iQueue->second.size() > mnMaximalRecentlyCacheCount)
479cdf0e10cSrcweir             iQueue->second.pop_back();
480cdf0e10cSrcweir     }
481cdf0e10cSrcweir }
482cdf0e10cSrcweir 
483cdf0e10cSrcweir 
484cdf0e10cSrcweir 
485cdf0e10cSrcweir } } } // end of namespace ::sd::slidesorter::cache
486