bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / slidesorter / cache / SlsRequestQueue.cxx
blob19fbc99cb769cd85a9f5bda94b903f83c3835166
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "SlsRequestQueue.hxx"
22 #include <set>
24 namespace sd { namespace slidesorter { namespace cache {
26 /** This class extends the actual request data with additional information
27 that is used by the priority queues.
29 class Request
31 public:
32 Request (
33 CacheKey aKey, sal_Int32 nPriority, RequestPriorityClass eClass)
34 : maKey(aKey), mnPriorityInClass(nPriority), meClass(eClass)
36 /** Sort requests according to priority classes and then to priorities.
38 class Comparator { public:
39 bool operator() (const Request& rRequest1, const Request& rRequest2)
41 if (rRequest1.meClass == rRequest2.meClass)
43 if (rRequest1.mnPriorityInClass == rRequest2.mnPriorityInClass)
45 return rRequest1.maKey < rRequest2.maKey;
47 return rRequest1.mnPriorityInClass > rRequest2.mnPriorityInClass;
49 return rRequest1.meClass < rRequest2.meClass;
52 /** Request data is compared arbitrarily by their addresses in memory.
53 This just establishes an order so that the STL containers are happy.
54 The order is not semantically interpreted.
56 class DataComparator
58 public:
59 DataComparator (const CacheKey aKey)
60 : maKey(aKey)
63 bool operator() (const Request& rRequest) const
65 return maKey == rRequest.maKey;
67 private:
68 const CacheKey maKey;
71 CacheKey maKey;
72 sal_Int32 mnPriorityInClass;
73 RequestPriorityClass meClass;
76 class RequestQueue::Container
77 : public ::std::set<
78 Request,
79 Request::Comparator>
83 //===== GenericRequestQueue =================================================
85 RequestQueue::RequestQueue (const SharedCacheContext& rpCacheContext)
86 : maMutex(),
87 mpRequestQueue(new Container()),
88 mpCacheContext(rpCacheContext),
89 mnMinimumPriority(0),
90 mnMaximumPriority(1)
94 RequestQueue::~RequestQueue()
96 Clear();
99 void RequestQueue::AddRequest (
100 CacheKey aKey,
101 RequestPriorityClass eRequestClass,
102 bool /*bInsertWithHighestPriority*/)
104 ::osl::MutexGuard aGuard (maMutex);
106 OSL_ASSERT(eRequestClass>=MIN__CLASS && eRequestClass<=MAX__CLASS);
108 // If the request is already a member of the queue then remove it so
109 // that the following insertion will use the new prioritization.
110 #if OSL_DEBUG_LEVEL >=2
111 bool bRemoved =
112 #endif
113 RemoveRequest(aKey);
115 // The priority of the request inside its priority class is defined by
116 // the page number. This ensures a strict top-to-bottom, left-to-right
117 // order.
118 sal_Int32 nPriority (mpCacheContext->GetPriority(aKey));
119 Request aRequest (aKey, nPriority, eRequestClass);
121 std::pair<Container::iterator,bool> ret = mpRequestQueue->insert(aRequest);
122 bool bInserted = ret.second;
124 if (bInserted)
126 SdrPage *pPage = const_cast<SdrPage*>(aRequest.maKey);
127 pPage->AddPageUser(*this);
130 SSCD_SET_REQUEST_CLASS(aKey,eRequestClass);
132 #if OSL_DEBUG_LEVEL >=2
133 SAL_INFO("sd.sls", OSL_THIS_FUNC << ": " << (bRemoved?"replaced":"added")
134 << " request for page " << ((aKey->GetPageNum()-1)/2)
135 << " with priority class " << static_cast<int>(eRequestClass));
136 #endif
139 void RequestQueue::PageInDestruction(const SdrPage& rPage)
141 //remove any requests pending for this page which is going away now
142 RemoveRequest(&rPage);
145 bool RequestQueue::RemoveRequest (
146 CacheKey aKey)
148 bool bRequestWasRemoved (false);
149 ::osl::MutexGuard aGuard (maMutex);
151 while(true)
153 Container::const_iterator aRequestIterator = ::std::find_if (
154 mpRequestQueue->begin(),
155 mpRequestQueue->end(),
156 Request::DataComparator(aKey));
157 if (aRequestIterator != mpRequestQueue->end())
159 if (aRequestIterator->mnPriorityInClass == mnMinimumPriority+1)
160 mnMinimumPriority++;
161 else if (aRequestIterator->mnPriorityInClass == mnMaximumPriority-1)
162 mnMaximumPriority--;
164 SdrPage *pPage = const_cast<SdrPage*>(aRequestIterator->maKey);
165 pPage->RemovePageUser(*this);
166 mpRequestQueue->erase(aRequestIterator);
168 bRequestWasRemoved = true;
170 if (bRequestWasRemoved)
172 SSCD_SET_STATUS(aKey,NONE);
175 else
176 break;
179 return bRequestWasRemoved;
182 void RequestQueue::ChangeClass (
183 CacheKey aKey,
184 RequestPriorityClass eNewRequestClass)
186 ::osl::MutexGuard aGuard (maMutex);
188 OSL_ASSERT(eNewRequestClass>=MIN__CLASS && eNewRequestClass<=MAX__CLASS);
190 Container::const_iterator iRequest (
191 ::std::find_if (
192 mpRequestQueue->begin(),
193 mpRequestQueue->end(),
194 Request::DataComparator(aKey)));
195 if (iRequest!=mpRequestQueue->end() && iRequest->meClass!=eNewRequestClass)
197 AddRequest(aKey, eNewRequestClass, true);
198 SSCD_SET_REQUEST_CLASS(aKey,eNewRequestClass);
202 CacheKey RequestQueue::GetFront()
204 ::osl::MutexGuard aGuard (maMutex);
206 if (mpRequestQueue->empty())
207 throw ::com::sun::star::uno::RuntimeException("RequestQueue::GetFront(): queue is empty",
208 NULL);
210 return mpRequestQueue->begin()->maKey;
213 RequestPriorityClass RequestQueue::GetFrontPriorityClass()
215 ::osl::MutexGuard aGuard (maMutex);
217 if (mpRequestQueue->empty())
218 throw ::com::sun::star::uno::RuntimeException("RequestQueue::GetFrontPriorityClass(): queue is empty",
219 NULL);
221 return mpRequestQueue->begin()->meClass;
224 void RequestQueue::PopFront()
226 ::osl::MutexGuard aGuard (maMutex);
228 if ( ! mpRequestQueue->empty())
230 SSCD_SET_STATUS(maRequestQueue.begin()->mpData->GetPage(),NONE);
232 Container::const_iterator aIter(mpRequestQueue->begin());
233 SdrPage *pPage = const_cast<SdrPage*>(aIter->maKey);
234 pPage->RemovePageUser(*this);
235 mpRequestQueue->erase(aIter);
237 // Reset the priority counter if possible.
238 if (mpRequestQueue->empty())
240 mnMinimumPriority = 0;
241 mnMaximumPriority = 1;
246 bool RequestQueue::IsEmpty()
248 ::osl::MutexGuard aGuard (maMutex);
249 return mpRequestQueue->empty();
252 void RequestQueue::Clear()
254 ::osl::MutexGuard aGuard (maMutex);
256 for (Container::iterator aI = mpRequestQueue->begin(), aEnd = mpRequestQueue->end(); aI != aEnd; ++aI)
258 SdrPage *pPage = const_cast<SdrPage*>(aI->maKey);
259 pPage->RemovePageUser(*this);
262 mpRequestQueue->clear();
263 mnMinimumPriority = 0;
264 mnMaximumPriority = 1;
267 } } } // end of namespace ::sd::slidesorter::cache
269 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */