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