Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "SlsRequestQueue.hxx"
31 : :
32 : : #include <set>
33 : :
34 : : namespace sd { namespace slidesorter { namespace cache {
35 : :
36 : : /** This class extends the actual request data with additional information
37 : : that is used by the priority queues.
38 : : */
39 : : class Request
40 : : {
41 : : public:
42 : 1243 : Request (
43 : : CacheKey aKey, sal_Int32 nPriority, RequestPriorityClass eClass)
44 : 1243 : : maKey(aKey), mnPriorityInClass(nPriority), meClass(eClass)
45 : 1243 : {}
46 : : /** Sort requests according to priority classes and then to priorities.
47 : : */
48 : : class Comparator { public:
49 : 446 : bool operator() (const Request& rRequest1, const Request& rRequest2)
50 : : {
51 [ + + ]: 446 : if (rRequest1.meClass == rRequest2.meClass)
52 : 235 : return (rRequest1.mnPriorityInClass > rRequest2.mnPriorityInClass);
53 : : else
54 : 446 : return (rRequest1.meClass < rRequest2.meClass);
55 : : }
56 : : };
57 : : /** Request data is compared arbitrarily by their addresses in memory.
58 : : This just establishes an order so that the STL containers are happy.
59 : : The order is not semantically interpreted.
60 : : */
61 : : class DataComparator { public:
62 : : DataComparator (const Request&rRequest):maKey(rRequest.maKey){}
63 : 3552 : DataComparator (const CacheKey aKey):maKey(aKey){}
64 : 2079 : bool operator() (const Request& rRequest) { return maKey == rRequest.maKey; }
65 : : private: const CacheKey maKey;
66 : : };
67 : :
68 : : CacheKey maKey;
69 : : sal_Int32 mnPriorityInClass;
70 : : RequestPriorityClass meClass;
71 : : };
72 : :
73 : :
74 : 260 : class RequestQueue::Container
75 : : : public ::std::set<
76 : : Request,
77 : : Request::Comparator>
78 : : {
79 : : };
80 : :
81 : :
82 : :
83 : :
84 : : //===== GenericRequestQueue =================================================
85 : :
86 : :
87 : 130 : RequestQueue::RequestQueue (const SharedCacheContext& rpCacheContext)
88 : : : maMutex(),
89 : 0 : mpRequestQueue(new Container()),
90 : : mpCacheContext(rpCacheContext),
91 : : mnMinimumPriority(0),
92 [ + - ][ + - ]: 130 : mnMaximumPriority(1)
[ + - ]
93 : : {
94 : 130 : }
95 : :
96 : :
97 : :
98 : :
99 [ + - ][ + - ]: 130 : RequestQueue::~RequestQueue (void)
100 : : {
101 : 130 : }
102 : :
103 : :
104 : :
105 : :
106 : 1243 : void RequestQueue::AddRequest (
107 : : CacheKey aKey,
108 : : RequestPriorityClass eRequestClass,
109 : : bool /*bInsertWithHighestPriority*/)
110 : : {
111 [ + - ]: 1243 : ::osl::MutexGuard aGuard (maMutex);
112 : :
113 : : OSL_ASSERT(eRequestClass>=MIN__CLASS && eRequestClass<=MAX__CLASS);
114 : :
115 : : // If the request is already a member of the queue then remove it so
116 : : // that the following insertion will use the new prioritization.
117 : : #if OSL_DEBUG_LEVEL >=2
118 : : bool bRemoved =
119 : : #endif
120 [ + - ]: 1243 : RemoveRequest(aKey);
121 : :
122 : : // The priority of the request inside its priority class is defined by
123 : : // the page number. This ensures a strict top-to-bottom, left-to-right
124 : : // order.
125 [ + - ]: 1243 : sal_Int32 nPriority (mpCacheContext->GetPriority(aKey));
126 : 1243 : Request aRequest (aKey, nPriority, eRequestClass);
127 [ + - ]: 1243 : mpRequestQueue->insert(aRequest);
128 : :
129 [ + - ]: 1243 : SSCD_SET_REQUEST_CLASS(aKey,eRequestClass);
130 : :
131 : : #if OSL_DEBUG_LEVEL >=2
132 : : SAL_INFO("sd.sls", OSL_THIS_FUNC << ": " << (bRemoved?"replaced":"added")
133 : : << " request for page " << ((aKey->GetPageNum()-1)/2)
134 : : << " with priority class " << static_cast<int>(eRequestClass));
135 : : #endif
136 : 1243 : }
137 : :
138 : :
139 : :
140 : :
141 : 1243 : bool RequestQueue::RemoveRequest (
142 : : CacheKey aKey)
143 : : {
144 : 1243 : bool bRequestWasRemoved (false);
145 [ + - ]: 1243 : ::osl::MutexGuard aGuard (maMutex);
146 : :
147 : 896 : while(true)
148 : : {
149 : : Container::const_iterator aRequestIterator = ::std::find_if (
150 : 2139 : mpRequestQueue->begin(),
151 : 2139 : mpRequestQueue->end(),
152 [ + - ]: 6417 : Request::DataComparator(aKey));
153 [ + + ]: 2139 : if (aRequestIterator != mpRequestQueue->end())
154 : : {
155 [ - + ]: 896 : if (aRequestIterator->mnPriorityInClass == mnMinimumPriority+1)
156 : 0 : mnMinimumPriority++;
157 [ + + ]: 896 : else if (aRequestIterator->mnPriorityInClass == mnMaximumPriority-1)
158 : 232 : mnMaximumPriority--;
159 [ + - ]: 896 : mpRequestQueue->erase(aRequestIterator);
160 : 896 : bRequestWasRemoved = true;
161 : :
162 : : if (bRequestWasRemoved)
163 : : {
164 : : SSCD_SET_STATUS(aKey,NONE);
165 : : }
166 : : }
167 : : else
168 : : break;
169 : : }
170 : :
171 [ + - ]: 1243 : return bRequestWasRemoved;
172 : : }
173 : :
174 : :
175 : :
176 : :
177 : 1413 : void RequestQueue::ChangeClass (
178 : : CacheKey aKey,
179 : : RequestPriorityClass eNewRequestClass)
180 : : {
181 [ + - ]: 1413 : ::osl::MutexGuard aGuard (maMutex);
182 : :
183 : : OSL_ASSERT(eNewRequestClass>=MIN__CLASS && eNewRequestClass<=MAX__CLASS);
184 : :
185 : : Container::const_iterator iRequest (
186 : : ::std::find_if (
187 : 1413 : mpRequestQueue->begin(),
188 : 1413 : mpRequestQueue->end(),
189 [ + - ]: 4239 : Request::DataComparator(aKey)));
190 [ + + ][ + + ]: 1413 : if (iRequest!=mpRequestQueue->end() && iRequest->meClass!=eNewRequestClass)
[ + - ][ + + ]
191 : : {
192 [ + - ]: 1 : AddRequest(aKey, eNewRequestClass, true);
193 : : SSCD_SET_REQUEST_CLASS(aKey,eNewRequestClass);
194 [ + - ]: 1413 : }
195 : 1413 : }
196 : :
197 : :
198 : :
199 : :
200 : 270 : CacheKey RequestQueue::GetFront (void)
201 : : {
202 [ + - ]: 270 : ::osl::MutexGuard aGuard (maMutex);
203 : :
204 [ - + ]: 270 : if (mpRequestQueue->empty())
205 : : throw ::com::sun::star::uno::RuntimeException("RequestQueue::GetFront(): queue is empty",
206 [ # # ][ # # ]: 0 : NULL);
207 : :
208 [ + - ]: 270 : return mpRequestQueue->begin()->maKey;
209 : : }
210 : :
211 : :
212 : :
213 : :
214 : 313 : RequestPriorityClass RequestQueue::GetFrontPriorityClass (void)
215 : : {
216 [ + - ]: 313 : ::osl::MutexGuard aGuard (maMutex);
217 : :
218 [ - + ]: 313 : if (mpRequestQueue->empty())
219 : : throw ::com::sun::star::uno::RuntimeException("RequestQueue::GetFrontPriorityClass(): queue is empty",
220 [ # # ][ # # ]: 0 : NULL);
221 : :
222 [ + - ]: 313 : return mpRequestQueue->begin()->meClass;
223 : : }
224 : :
225 : :
226 : :
227 : :
228 : 270 : void RequestQueue::PopFront (void)
229 : : {
230 [ + - ]: 270 : ::osl::MutexGuard aGuard (maMutex);
231 : :
232 [ + - ]: 270 : if ( ! mpRequestQueue->empty())
233 : : {
234 : : SSCD_SET_STATUS(maRequestQueue.begin()->mpData->GetPage(),NONE);
235 : :
236 [ + - ]: 270 : mpRequestQueue->erase(mpRequestQueue->begin());
237 : :
238 : : // Reset the priority counter if possible.
239 [ + + ]: 270 : if (mpRequestQueue->empty())
240 : : {
241 : 227 : mnMinimumPriority = 0;
242 : 227 : mnMaximumPriority = 1;
243 : : }
244 [ + - ]: 270 : }
245 : 270 : }
246 : :
247 : :
248 : :
249 : :
250 : 810 : bool RequestQueue::IsEmpty (void)
251 : : {
252 [ + - ]: 810 : ::osl::MutexGuard aGuard (maMutex);
253 [ + - ]: 810 : return mpRequestQueue->empty();
254 : : }
255 : :
256 : :
257 : :
258 : :
259 : 130 : void RequestQueue::Clear (void)
260 : : {
261 [ + - ]: 130 : ::osl::MutexGuard aGuard (maMutex);
262 : :
263 : 130 : mpRequestQueue->clear();
264 : 130 : mnMinimumPriority = 0;
265 [ + - ]: 130 : mnMaximumPriority = 1;
266 : 130 : }
267 : :
268 : :
269 : :
270 : :
271 : 540 : ::osl::Mutex& RequestQueue::GetMutex (void)
272 : : {
273 : 540 : return maMutex;
274 : : }
275 : :
276 : :
277 : : } } } // end of namespace ::sd::slidesorter::cache
278 : :
279 : :
280 : :
281 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|