1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
23 #include <sal/log.hxx>
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.
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
)
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.
63 explicit DataComparator (const CacheKey aKey
)
67 bool operator() (const Request
& rRequest
) const
69 return maKey
== rRequest
.maKey
;
76 sal_Int32
const mnPriorityInClass
;
77 RequestPriorityClass
const meClass
;
80 class RequestQueue::Container
87 //===== GenericRequestQueue =================================================
89 RequestQueue::RequestQueue (const SharedCacheContext
& rpCacheContext
)
91 mpRequestQueue(new Container
),
92 mpCacheContext(rpCacheContext
),
98 RequestQueue::~RequestQueue()
103 void RequestQueue::AddRequest (
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
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
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
;
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
));
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
151 RequestQueue::RemoveRequest(
154 ::osl::MutexGuard
aGuard (maMutex
);
155 #if OSL_DEBUG_LEVEL >=2
156 bool bIsRemoved
= false;
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)
168 else if (aRequestIterator
->mnPriorityInClass
== mnMaximumPriority
-1)
171 SdrPage
*pPage
= const_cast<SdrPage
*>(aRequestIterator
->maKey
);
172 pPage
->RemovePageUser(*this);
173 mpRequestQueue
->erase(aRequestIterator
);
174 #if OSL_DEBUG_LEVEL >=2
181 #if OSL_DEBUG_LEVEL >=2
187 void RequestQueue::ChangeClass (
189 RequestPriorityClass eNewRequestClass
)
191 ::osl::MutexGuard
aGuard (maMutex
);
193 assert(eNewRequestClass
>=MIN_CLASS
&& eNewRequestClass
<=MAX_CLASS
);
195 Container::const_iterator
iRequest (
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",
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",
225 return mpRequestQueue
->begin()->meClass
;
228 void RequestQueue::PopFront()
230 ::osl::MutexGuard
aGuard (maMutex
);
232 if ( mpRequestQueue
->empty())
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: */