xref: /AOO41X/main/sd/source/ui/slidesorter/cache/SlsRequestQueue.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
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 #include "precompiled_sd.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "SlsRequestQueue.hxx"
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <set>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #undef VERBOSE
32cdf0e10cSrcweir //#define VERBOSE
33cdf0e10cSrcweir 
34cdf0e10cSrcweir namespace sd { namespace slidesorter { namespace cache {
35cdf0e10cSrcweir 
36cdf0e10cSrcweir /** This class extends the actual request data with additional information
37cdf0e10cSrcweir     that is used by the priority queues.
38cdf0e10cSrcweir */
39cdf0e10cSrcweir class Request
40cdf0e10cSrcweir {
41cdf0e10cSrcweir public:
Request(CacheKey aKey,sal_Int32 nPriority,RequestPriorityClass eClass)42cdf0e10cSrcweir     Request (
43cdf0e10cSrcweir         CacheKey aKey, sal_Int32 nPriority, RequestPriorityClass eClass)
44cdf0e10cSrcweir         : maKey(aKey), mnPriorityInClass(nPriority), meClass(eClass)
45cdf0e10cSrcweir     {}
46cdf0e10cSrcweir     /** Sort requests according to priority classes and then to priorities.
47cdf0e10cSrcweir     */
48cdf0e10cSrcweir     class Comparator { public:
operator ()(const Request & rRequest1,const Request & rRequest2)49cdf0e10cSrcweir         bool operator() (const Request& rRequest1, const Request& rRequest2)
50cdf0e10cSrcweir         {
51cdf0e10cSrcweir             if (rRequest1.meClass == rRequest2.meClass)
52cdf0e10cSrcweir                 return (rRequest1.mnPriorityInClass > rRequest2.mnPriorityInClass);
53cdf0e10cSrcweir             else
54cdf0e10cSrcweir                 return (rRequest1.meClass < rRequest2.meClass);
55cdf0e10cSrcweir         }
56cdf0e10cSrcweir     };
57cdf0e10cSrcweir     /** Request data is compared arbitrarily by their addresses in memory.
58cdf0e10cSrcweir         This just establishes an order so that the STL containers are happy.
59cdf0e10cSrcweir         The order is not semantically interpreted.
60cdf0e10cSrcweir     */
61cdf0e10cSrcweir     class DataComparator { public:
DataComparator(const Request & rRequest)62cdf0e10cSrcweir         DataComparator (const Request&rRequest):maKey(rRequest.maKey){}
DataComparator(const CacheKey aKey)63cdf0e10cSrcweir         DataComparator (const CacheKey aKey):maKey(aKey){}
operator ()(const Request & rRequest)64cdf0e10cSrcweir         bool operator() (const Request& rRequest) { return maKey == rRequest.maKey; }
65cdf0e10cSrcweir     private: const CacheKey maKey;
66cdf0e10cSrcweir     };
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     CacheKey maKey;
69cdf0e10cSrcweir     sal_Int32 mnPriorityInClass;
70cdf0e10cSrcweir     RequestPriorityClass meClass;
71cdf0e10cSrcweir };
72cdf0e10cSrcweir 
73cdf0e10cSrcweir 
74cdf0e10cSrcweir class RequestQueue::Container
75cdf0e10cSrcweir     : public ::std::set<
76cdf0e10cSrcweir         Request,
77cdf0e10cSrcweir         Request::Comparator>
78cdf0e10cSrcweir {
79cdf0e10cSrcweir };
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 
84cdf0e10cSrcweir //=====  GenericRequestQueue  =================================================
85cdf0e10cSrcweir 
86cdf0e10cSrcweir 
RequestQueue(const SharedCacheContext & rpCacheContext)87cdf0e10cSrcweir RequestQueue::RequestQueue (const SharedCacheContext& rpCacheContext)
88cdf0e10cSrcweir     : maMutex(),
89cdf0e10cSrcweir       mpRequestQueue(new Container()),
90cdf0e10cSrcweir       mpCacheContext(rpCacheContext),
91cdf0e10cSrcweir       mnMinimumPriority(0),
92cdf0e10cSrcweir       mnMaximumPriority(1)
93cdf0e10cSrcweir {
94cdf0e10cSrcweir }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 
~RequestQueue(void)99cdf0e10cSrcweir RequestQueue::~RequestQueue (void)
100cdf0e10cSrcweir {
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 
AddRequest(CacheKey aKey,RequestPriorityClass eRequestClass,bool)106cdf0e10cSrcweir void RequestQueue::AddRequest (
107cdf0e10cSrcweir     CacheKey aKey,
108cdf0e10cSrcweir     RequestPriorityClass eRequestClass,
109cdf0e10cSrcweir     bool /*bInsertWithHighestPriority*/)
110cdf0e10cSrcweir {
111cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     OSL_ASSERT(eRequestClass>=MIN__CLASS && eRequestClass<=MAX__CLASS);
114cdf0e10cSrcweir 
115cdf0e10cSrcweir     // If the request is already a member of the queue then remove it so
116cdf0e10cSrcweir     // that the following insertion will use the new prioritization.
117cdf0e10cSrcweir #ifdef VERBOSE
118cdf0e10cSrcweir     bool bRemoved =
119cdf0e10cSrcweir #endif
120cdf0e10cSrcweir 		RemoveRequest(aKey);
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     // The priority of the request inside its priority class is defined by
123cdf0e10cSrcweir     // the page number.  This ensures a strict top-to-bottom, left-to-right
124cdf0e10cSrcweir     // order.
125cdf0e10cSrcweir     sal_Int32 nPriority (mpCacheContext->GetPriority(aKey));
126cdf0e10cSrcweir     Request aRequest (aKey, nPriority, eRequestClass);
127cdf0e10cSrcweir     mpRequestQueue->insert(aRequest);
128cdf0e10cSrcweir 
129cdf0e10cSrcweir     SSCD_SET_REQUEST_CLASS(rRequestData.GetPage(),eRequestClass);
130cdf0e10cSrcweir 
131cdf0e10cSrcweir #ifdef VERBOSE
132cdf0e10cSrcweir     OSL_TRACE("%s request for page %d with priority class %d",
133cdf0e10cSrcweir         bRemoved?"replaced":"added",
134cdf0e10cSrcweir         (rRequestData.GetPage()->GetPageNum()-1)/2,
135cdf0e10cSrcweir         eRequestClass);
136cdf0e10cSrcweir #endif
137cdf0e10cSrcweir }
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 
RemoveRequest(CacheKey aKey)142cdf0e10cSrcweir bool RequestQueue::RemoveRequest (
143cdf0e10cSrcweir     CacheKey aKey)
144cdf0e10cSrcweir {
145cdf0e10cSrcweir     bool bRequestWasRemoved (false);
146cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     while(true)
149cdf0e10cSrcweir     {
150cdf0e10cSrcweir         Container::const_iterator aRequestIterator = ::std::find_if (
151cdf0e10cSrcweir             mpRequestQueue->begin(),
152cdf0e10cSrcweir             mpRequestQueue->end(),
153cdf0e10cSrcweir             Request::DataComparator(aKey));
154cdf0e10cSrcweir         if (aRequestIterator != mpRequestQueue->end())
155cdf0e10cSrcweir         {
156cdf0e10cSrcweir             if (aRequestIterator->mnPriorityInClass == mnMinimumPriority+1)
157cdf0e10cSrcweir                 mnMinimumPriority++;
158cdf0e10cSrcweir             else if (aRequestIterator->mnPriorityInClass == mnMaximumPriority-1)
159cdf0e10cSrcweir                 mnMaximumPriority--;
160cdf0e10cSrcweir             mpRequestQueue->erase(aRequestIterator);
161cdf0e10cSrcweir             bRequestWasRemoved = true;
162cdf0e10cSrcweir 
163cdf0e10cSrcweir             if (bRequestWasRemoved)
164cdf0e10cSrcweir             {
165cdf0e10cSrcweir                 SSCD_SET_STATUS(rRequest.GetPage(),NONE);
166cdf0e10cSrcweir             }
167cdf0e10cSrcweir         }
168cdf0e10cSrcweir         else
169cdf0e10cSrcweir             break;
170cdf0e10cSrcweir     }
171cdf0e10cSrcweir 
172cdf0e10cSrcweir     return bRequestWasRemoved;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 
ChangeClass(CacheKey aKey,RequestPriorityClass eNewRequestClass)178cdf0e10cSrcweir void RequestQueue::ChangeClass (
179cdf0e10cSrcweir     CacheKey aKey,
180cdf0e10cSrcweir     RequestPriorityClass eNewRequestClass)
181cdf0e10cSrcweir {
182cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     OSL_ASSERT(eNewRequestClass>=MIN__CLASS && eNewRequestClass<=MAX__CLASS);
185cdf0e10cSrcweir 
186cdf0e10cSrcweir     Container::const_iterator iRequest (
187cdf0e10cSrcweir         ::std::find_if (
188cdf0e10cSrcweir             mpRequestQueue->begin(),
189cdf0e10cSrcweir             mpRequestQueue->end(),
190cdf0e10cSrcweir             Request::DataComparator(aKey)));
191cdf0e10cSrcweir     if (iRequest!=mpRequestQueue->end() && iRequest->meClass!=eNewRequestClass)
192cdf0e10cSrcweir     {
193cdf0e10cSrcweir         AddRequest(aKey, eNewRequestClass, true);
194cdf0e10cSrcweir         SSCD_SET_REQUEST_CLASS(rRequestData.GetPage(),eNewRequestClass);
195cdf0e10cSrcweir     }
196cdf0e10cSrcweir }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 
GetFront(void)201cdf0e10cSrcweir CacheKey RequestQueue::GetFront (void)
202cdf0e10cSrcweir {
203cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     if (mpRequestQueue->empty())
206cdf0e10cSrcweir         throw ::com::sun::star::uno::RuntimeException(
207cdf0e10cSrcweir             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
208cdf0e10cSrcweir                 "RequestQueue::GetFront(): queue is empty")),
209cdf0e10cSrcweir             NULL);
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     return mpRequestQueue->begin()->maKey;
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 
GetFrontPriorityClass(void)217cdf0e10cSrcweir RequestPriorityClass RequestQueue::GetFrontPriorityClass (void)
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     if (mpRequestQueue->empty())
222cdf0e10cSrcweir         throw ::com::sun::star::uno::RuntimeException(
223cdf0e10cSrcweir             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
224cdf0e10cSrcweir                 "RequestQueue::GetFrontPriorityClass(): queue is empty")),
225cdf0e10cSrcweir             NULL);
226cdf0e10cSrcweir 
227cdf0e10cSrcweir     return mpRequestQueue->begin()->meClass;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 
232cdf0e10cSrcweir 
PopFront(void)233cdf0e10cSrcweir void RequestQueue::PopFront (void)
234cdf0e10cSrcweir {
235cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     if ( ! mpRequestQueue->empty())
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir         SSCD_SET_STATUS(maRequestQueue.begin()->mpData->GetPage(),NONE);
240cdf0e10cSrcweir 
241cdf0e10cSrcweir         mpRequestQueue->erase(mpRequestQueue->begin());
242cdf0e10cSrcweir 
243cdf0e10cSrcweir         // Reset the priority counter if possible.
244cdf0e10cSrcweir         if (mpRequestQueue->empty())
245cdf0e10cSrcweir         {
246cdf0e10cSrcweir             mnMinimumPriority = 0;
247cdf0e10cSrcweir             mnMaximumPriority = 1;
248cdf0e10cSrcweir         }
249cdf0e10cSrcweir     }
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 
IsEmpty(void)255cdf0e10cSrcweir bool RequestQueue::IsEmpty (void)
256cdf0e10cSrcweir {
257cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
258cdf0e10cSrcweir     return mpRequestQueue->empty();
259cdf0e10cSrcweir }
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 
Clear(void)264cdf0e10cSrcweir void RequestQueue::Clear (void)
265cdf0e10cSrcweir {
266cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
267cdf0e10cSrcweir 
268cdf0e10cSrcweir     mpRequestQueue->clear();
269cdf0e10cSrcweir     mnMinimumPriority = 0;
270cdf0e10cSrcweir     mnMaximumPriority = 1;
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 
275cdf0e10cSrcweir 
GetMutex(void)276cdf0e10cSrcweir ::osl::Mutex& RequestQueue::GetMutex (void)
277cdf0e10cSrcweir {
278cdf0e10cSrcweir     return maMutex;
279cdf0e10cSrcweir }
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 
282cdf0e10cSrcweir } } } // end of namespace ::sd::slidesorter::cache
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 
286