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"
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.
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.
59 DataComparator (const CacheKey aKey
)
63 bool operator() (const Request
& rRequest
) const
65 return maKey
== rRequest
.maKey
;
72 sal_Int32 mnPriorityInClass
;
73 RequestPriorityClass meClass
;
76 class RequestQueue::Container
83 //===== GenericRequestQueue =================================================
85 RequestQueue::RequestQueue (const SharedCacheContext
& rpCacheContext
)
87 mpRequestQueue(new Container()),
88 mpCacheContext(rpCacheContext
),
94 RequestQueue::~RequestQueue()
99 void RequestQueue::AddRequest (
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
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
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
;
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
));
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 (
148 bool bRequestWasRemoved (false);
149 ::osl::MutexGuard
aGuard (maMutex
);
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)
161 else if (aRequestIterator
->mnPriorityInClass
== mnMaximumPriority
-1)
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
);
179 return bRequestWasRemoved
;
182 void RequestQueue::ChangeClass (
184 RequestPriorityClass eNewRequestClass
)
186 ::osl::MutexGuard
aGuard (maMutex
);
188 OSL_ASSERT(eNewRequestClass
>=MIN__CLASS
&& eNewRequestClass
<=MAX__CLASS
);
190 Container::const_iterator
iRequest (
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",
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",
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: */