LibreOffice Module sd (master) 1
SlsRequestQueue.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "SlsRequestQueue.hxx"
21
22#include <sal/log.hxx>
23
24#include <svx/svdpage.hxx>
25
26#include <set>
27#include <utility>
28
29namespace sd::slidesorter::cache {
30
31namespace {
32
36class Request
37{
38public:
39 Request (
40 CacheKey aKey, sal_Int32 nPriority, RequestPriorityClass eClass)
41 : maKey(aKey), mnPriorityInClass(nPriority), meClass(eClass)
42 {}
45 class Comparator { public:
46 bool operator() (const Request& rRequest1, const Request& rRequest2)
47 const
48 {
49 if (rRequest1.meClass == rRequest2.meClass)
50 {
51 if (rRequest1.mnPriorityInClass == rRequest2.mnPriorityInClass)
52 {
53 return rRequest1.maKey < rRequest2.maKey;
54 }
55 return rRequest1.mnPriorityInClass > rRequest2.mnPriorityInClass;
56 }
57 return rRequest1.meClass < rRequest2.meClass;
58 }
59 };
64 class DataComparator
65 {
66 public:
67 explicit DataComparator (const CacheKey aKey)
68 : maKey(aKey)
69 {
70 }
71 bool operator() (const Request& rRequest) const
72 {
73 return maKey == rRequest.maKey;
74 }
75 private:
77 };
78
82};
83
84}
85
87 : public ::std::set<
88 Request,
89 Request::Comparator>
90{
91};
92
93//===== GenericRequestQueue =================================================
94
96 : mpRequestQueue(new Container),
97 mpCacheContext(std::move(pCacheContext)),
98 mnMinimumPriority(0),
99 mnMaximumPriority(1)
100{
101}
102
104{
105 Clear();
106}
107
109 CacheKey aKey,
110 RequestPriorityClass eRequestClass)
111{
112 ::osl::MutexGuard aGuard (maMutex);
113
114 assert(eRequestClass>=MIN_CLASS && eRequestClass<=MAX_CLASS);
115
116 // If the request is already a member of the queue then remove it so
117 // that the following insertion will use the new prioritization.
118#if OSL_DEBUG_LEVEL >=2
119 bool bRemoved =
120#endif
121 RemoveRequest(aKey);
122
123 // The priority of the request inside its priority class is defined by
124 // the page number. This ensures a strict top-to-bottom, left-to-right
125 // order.
126 sal_Int32 nPriority (mpCacheContext->GetPriority(aKey));
127 Request aRequest (aKey, nPriority, eRequestClass);
128
129 std::pair<Container::iterator,bool> ret = mpRequestQueue->insert(aRequest);
130 bool bInserted = ret.second;
131
132 if (bInserted)
133 {
134 SdrPage *pPage = const_cast<SdrPage*>(aRequest.maKey);
135 pPage->AddPageUser(*this);
136 }
137
138#if OSL_DEBUG_LEVEL >=2
139 SAL_INFO("sd.sls", __func__ << ": " << (bRemoved?"replaced":"added")
140 << " request for page " << ((aKey->GetPageNum()-1)/2)
141 << " with priority class " << static_cast<int>(eRequestClass));
142#endif
143}
144
146{
147 //remove any requests pending for this page which is going away now
148 RemoveRequest(&rPage);
149}
150
151#if OSL_DEBUG_LEVEL >=2
152bool
153#else
154void
155#endif
157 CacheKey aKey)
158{
159 ::osl::MutexGuard aGuard (maMutex);
160#if OSL_DEBUG_LEVEL >=2
161 bool bIsRemoved = false;
162#endif
163 while(true)
164 {
165 Container::const_iterator aRequestIterator = ::std::find_if (
166 mpRequestQueue->begin(),
167 mpRequestQueue->end(),
168 Request::DataComparator(aKey));
169 if (aRequestIterator != mpRequestQueue->end())
170 {
171 if (aRequestIterator->mnPriorityInClass == mnMinimumPriority+1)
173 else if (aRequestIterator->mnPriorityInClass == mnMaximumPriority-1)
175
176 SdrPage *pPage = const_cast<SdrPage*>(aRequestIterator->maKey);
177 pPage->RemovePageUser(*this);
178 mpRequestQueue->erase(aRequestIterator);
179#if OSL_DEBUG_LEVEL >=2
180 bIsRemoved = true;
181#endif
182 }
183 else
184 break;
185 }
186#if OSL_DEBUG_LEVEL >=2
187 return bIsRemoved;
188#endif
189
190}
191
193 CacheKey aKey,
194 RequestPriorityClass eNewRequestClass)
195{
196 ::osl::MutexGuard aGuard (maMutex);
197
198 assert(eNewRequestClass>=MIN_CLASS && eNewRequestClass<=MAX_CLASS);
199
200 Container::const_iterator iRequest (
201 ::std::find_if (
202 mpRequestQueue->begin(),
203 mpRequestQueue->end(),
204 Request::DataComparator(aKey)));
205 if (iRequest!=mpRequestQueue->end() && iRequest->meClass!=eNewRequestClass)
206 {
207 AddRequest(aKey, eNewRequestClass);
208 }
209}
210
212{
213 ::osl::MutexGuard aGuard (maMutex);
214
215 if (mpRequestQueue->empty())
216 throw css::uno::RuntimeException("RequestQueue::GetFront(): queue is empty",
217 nullptr);
218
219 return mpRequestQueue->begin()->maKey;
220}
221
223{
224 ::osl::MutexGuard aGuard (maMutex);
225
226 if (mpRequestQueue->empty())
227 throw css::uno::RuntimeException("RequestQueue::GetFrontPriorityClass(): queue is empty",
228 nullptr);
229
230 return mpRequestQueue->begin()->meClass;
231}
232
234{
235 ::osl::MutexGuard aGuard (maMutex);
236
237 if ( mpRequestQueue->empty())
238 return;
239
240 Container::const_iterator aIter(mpRequestQueue->begin());
241 SdrPage *pPage = const_cast<SdrPage*>(aIter->maKey);
242 pPage->RemovePageUser(*this);
243 mpRequestQueue->erase(aIter);
244
245 // Reset the priority counter if possible.
246 if (mpRequestQueue->empty())
247 {
250 }
251}
252
254{
255 ::osl::MutexGuard aGuard (maMutex);
256 return mpRequestQueue->empty();
257}
258
260{
261 ::osl::MutexGuard aGuard (maMutex);
262
263 for (const auto& rItem : *mpRequestQueue)
264 {
265 SdrPage *pPage = const_cast<SdrPage*>(rItem.maKey);
266 pPage->RemovePageUser(*this);
267 }
268
269 mpRequestQueue->clear();
272}
273
274} // end of namespace ::sd::slidesorter::cache
275
276/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const CacheKey maKey
sal_Int32 mnPriorityInClass
RequestPriorityClass meClass
sal_uInt16 GetPageNum() const
void RemovePageUser(sdr::PageUser &rOldUser)
void AddPageUser(sdr::PageUser &rNewUser)
bool IsEmpty()
Returns <TRUE> when there is no element in the queue.
int mnMaximumPriority
An upper bound of the highest priority of all elements in the queues.
bool RemoveRequest(CacheKey aKey)
Remove the specified request from the queue.
std::unique_ptr< Container > mpRequestQueue
void AddRequest(CacheKey aKey, RequestPriorityClass eRequestClass)
Insert a request with highest or lowest priority in its priority class.
RequestQueue(SharedCacheContext pCacheContext)
RequestPriorityClass GetFrontPriorityClass()
void PopFront()
Really a synonym for RemoveRequest(GetFront());.
virtual void PageInDestruction(const SdrPage &rPage) override
Ensure we don't hand out a page deleted before anyone got a chance to process it.
void Clear()
Remove all requests from the queue.
void ChangeClass(CacheKey aKey, RequestPriorityClass eNewRequestClass)
Change the priority class of the specified request.
int mnMinimumPriority
A lower bound of the lowest priority of all elements in the queues.
CacheKey GetFront()
Get the request with the highest priority int the highest priority class.
#define SAL_INFO(area, stream)
const SdrPage * CacheKey
RequestPriorityClass
Each request for a preview creation has a priority.
std::shared_ptr< CacheContext > SharedCacheContext