bump product version to 6.3.0.0.beta1
[LibreOffice.git] / sd / source / ui / slidesorter / cache / SlsRequestQueue.cxx
blob4d07bd5977b3e78de89cf8a76500c66bb693351e
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"
21 #include <sdpage.hxx>
23 #include <sal/log.hxx>
25 #include <set>
27 namespace sd { namespace slidesorter { namespace cache {
29 /** This class extends the actual request data with additional information
30 that is used by the priority queues.
32 class Request
34 public:
35 Request (
36 CacheKey aKey, sal_Int32 nPriority, RequestPriorityClass eClass)
37 : maKey(aKey), mnPriorityInClass(nPriority), meClass(eClass)
39 /** Sort requests according to priority classes and then to priorities.
41 class Comparator { public:
42 bool operator() (const Request& rRequest1, const Request& rRequest2)
43 const
45 if (rRequest1.meClass == rRequest2.meClass)
47 if (rRequest1.mnPriorityInClass == rRequest2.mnPriorityInClass)
49 return rRequest1.maKey < rRequest2.maKey;
51 return rRequest1.mnPriorityInClass > rRequest2.mnPriorityInClass;
53 return rRequest1.meClass < rRequest2.meClass;
56 /** Request data is compared arbitrarily by their addresses in memory.
57 This just establishes an order so that the STL containers are happy.
58 The order is not semantically interpreted.
60 class DataComparator
62 public:
63 explicit DataComparator (const CacheKey aKey)
64 : maKey(aKey)
67 bool operator() (const Request& rRequest) const
69 return maKey == rRequest.maKey;
71 private:
72 const CacheKey maKey;
75 CacheKey const maKey;
76 sal_Int32 const mnPriorityInClass;
77 RequestPriorityClass const meClass;
80 class RequestQueue::Container
81 : public ::std::set<
82 Request,
83 Request::Comparator>
87 //===== GenericRequestQueue =================================================
89 RequestQueue::RequestQueue (const SharedCacheContext& rpCacheContext)
90 : maMutex(),
91 mpRequestQueue(new Container),
92 mpCacheContext(rpCacheContext),
93 mnMinimumPriority(0),
94 mnMaximumPriority(1)
98 RequestQueue::~RequestQueue()
100 Clear();
103 void RequestQueue::AddRequest (
104 CacheKey aKey,
105 RequestPriorityClass eRequestClass)
107 ::osl::MutexGuard aGuard (maMutex);
109 assert(eRequestClass>=MIN_CLASS && eRequestClass<=MAX_CLASS);
111 // If the request is already a member of the queue then remove it so
112 // that the following insertion will use the new prioritization.
113 #if OSL_DEBUG_LEVEL >=2
114 bool bRemoved =
115 #endif
116 RemoveRequest(aKey);
118 // The priority of the request inside its priority class is defined by
119 // the page number. This ensures a strict top-to-bottom, left-to-right
120 // order.
121 sal_Int32 nPriority (mpCacheContext->GetPriority(aKey));
122 Request aRequest (aKey, nPriority, eRequestClass);
124 std::pair<Container::iterator,bool> ret = mpRequestQueue->insert(aRequest);
125 bool bInserted = ret.second;
127 if (bInserted)
129 SdrPage *pPage = const_cast<SdrPage*>(aRequest.maKey);
130 pPage->AddPageUser(*this);
133 #if OSL_DEBUG_LEVEL >=2
134 SAL_INFO("sd.sls", OSL_THIS_FUNC << ": " << (bRemoved?"replaced":"added")
135 << " request for page " << ((aKey->GetPageNum()-1)/2)
136 << " with priority class " << static_cast<int>(eRequestClass));
137 #endif
140 void RequestQueue::PageInDestruction(const SdrPage& rPage)
142 //remove any requests pending for this page which is going away now
143 RemoveRequest(&rPage);
146 #if OSL_DEBUG_LEVEL >=2
147 bool
148 #else
149 void
150 #endif
151 RequestQueue::RemoveRequest(
152 CacheKey aKey)
154 ::osl::MutexGuard aGuard (maMutex);
155 #if OSL_DEBUG_LEVEL >=2
156 bool bIsRemoved = false;
157 #endif
158 while(true)
160 Container::const_iterator aRequestIterator = ::std::find_if (
161 mpRequestQueue->begin(),
162 mpRequestQueue->end(),
163 Request::DataComparator(aKey));
164 if (aRequestIterator != mpRequestQueue->end())
166 if (aRequestIterator->mnPriorityInClass == mnMinimumPriority+1)
167 mnMinimumPriority++;
168 else if (aRequestIterator->mnPriorityInClass == mnMaximumPriority-1)
169 mnMaximumPriority--;
171 SdrPage *pPage = const_cast<SdrPage*>(aRequestIterator->maKey);
172 pPage->RemovePageUser(*this);
173 mpRequestQueue->erase(aRequestIterator);
174 #if OSL_DEBUG_LEVEL >=2
175 bIsRemoved = true;
176 #endif
178 else
179 break;
181 #if OSL_DEBUG_LEVEL >=2
182 return bIsRemoved;
183 #endif
187 void RequestQueue::ChangeClass (
188 CacheKey aKey,
189 RequestPriorityClass eNewRequestClass)
191 ::osl::MutexGuard aGuard (maMutex);
193 assert(eNewRequestClass>=MIN_CLASS && eNewRequestClass<=MAX_CLASS);
195 Container::const_iterator iRequest (
196 ::std::find_if (
197 mpRequestQueue->begin(),
198 mpRequestQueue->end(),
199 Request::DataComparator(aKey)));
200 if (iRequest!=mpRequestQueue->end() && iRequest->meClass!=eNewRequestClass)
202 AddRequest(aKey, eNewRequestClass);
206 CacheKey RequestQueue::GetFront()
208 ::osl::MutexGuard aGuard (maMutex);
210 if (mpRequestQueue->empty())
211 throw css::uno::RuntimeException("RequestQueue::GetFront(): queue is empty",
212 nullptr);
214 return mpRequestQueue->begin()->maKey;
217 RequestPriorityClass RequestQueue::GetFrontPriorityClass()
219 ::osl::MutexGuard aGuard (maMutex);
221 if (mpRequestQueue->empty())
222 throw css::uno::RuntimeException("RequestQueue::GetFrontPriorityClass(): queue is empty",
223 nullptr);
225 return mpRequestQueue->begin()->meClass;
228 void RequestQueue::PopFront()
230 ::osl::MutexGuard aGuard (maMutex);
232 if ( mpRequestQueue->empty())
233 return;
235 Container::const_iterator aIter(mpRequestQueue->begin());
236 SdrPage *pPage = const_cast<SdrPage*>(aIter->maKey);
237 pPage->RemovePageUser(*this);
238 mpRequestQueue->erase(aIter);
240 // Reset the priority counter if possible.
241 if (mpRequestQueue->empty())
243 mnMinimumPriority = 0;
244 mnMaximumPriority = 1;
248 bool RequestQueue::IsEmpty()
250 ::osl::MutexGuard aGuard (maMutex);
251 return mpRequestQueue->empty();
254 void RequestQueue::Clear()
256 ::osl::MutexGuard aGuard (maMutex);
258 for (const auto& rItem : *mpRequestQueue)
260 SdrPage *pPage = const_cast<SdrPage*>(rItem.maKey);
261 pPage->RemovePageUser(*this);
264 mpRequestQueue->clear();
265 mnMinimumPriority = 0;
266 mnMaximumPriority = 1;
269 } } } // end of namespace ::sd::slidesorter::cache
271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */