diff options
Diffstat (limited to 'sd/source/ui/slidesorter/cache/SlsRequestQueue.cxx')
-rw-r--r-- | sd/source/ui/slidesorter/cache/SlsRequestQueue.cxx | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/sd/source/ui/slidesorter/cache/SlsRequestQueue.cxx b/sd/source/ui/slidesorter/cache/SlsRequestQueue.cxx new file mode 100644 index 000000000000..ccd590131343 --- /dev/null +++ b/sd/source/ui/slidesorter/cache/SlsRequestQueue.cxx @@ -0,0 +1,291 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "precompiled_sd.hxx" + +#include "SlsRequestQueue.hxx" + +#include <set> + + +#undef VERBOSE +//#define VERBOSE + +namespace sd { namespace slidesorter { namespace cache { + +/** This class extends the actual request data with additional information + that is used by the priority queues. +*/ +class Request +{ +public: + Request ( + CacheKey aKey, sal_Int32 nPriority, RequestPriorityClass eClass) + : maKey(aKey), mnPriorityInClass(nPriority), meClass(eClass) + {} + /** Sort requests according to priority classes and then to priorities. + */ + class Comparator { public: + bool operator() (const Request& rRequest1, const Request& rRequest2) + { + if (rRequest1.meClass == rRequest2.meClass) + return (rRequest1.mnPriorityInClass > rRequest2.mnPriorityInClass); + else + return (rRequest1.meClass < rRequest2.meClass); + } + }; + /** Request data is compared arbitrarily by their addresses in memory. + This just establishes an order so that the STL containers are happy. + The order is not semantically interpreted. + */ + class DataComparator { public: + DataComparator (const Request&rRequest):maKey(rRequest.maKey){} + DataComparator (const CacheKey aKey):maKey(aKey){} + bool operator() (const Request& rRequest) { return maKey == rRequest.maKey; } + private: const CacheKey maKey; + }; + + CacheKey maKey; + sal_Int32 mnPriorityInClass; + RequestPriorityClass meClass; +}; + + +class RequestQueue::Container + : public ::std::set< + Request, + Request::Comparator> +{ +}; + + + + +//===== GenericRequestQueue ================================================= + + +RequestQueue::RequestQueue (const SharedCacheContext& rpCacheContext) + : maMutex(), + mpRequestQueue(new Container()), + mpCacheContext(rpCacheContext), + mnMinimumPriority(0), + mnMaximumPriority(1) +{ +} + + + + +RequestQueue::~RequestQueue (void) +{ +} + + + + +void RequestQueue::AddRequest ( + CacheKey aKey, + RequestPriorityClass eRequestClass, + bool /*bInsertWithHighestPriority*/) +{ + ::osl::MutexGuard aGuard (maMutex); + + OSL_ASSERT(eRequestClass>=MIN__CLASS && eRequestClass<=MAX__CLASS); + + // If the request is already a member of the queue then remove it so + // that the following insertion will use the new prioritization. +#ifdef VERBOSE + bool bRemoved = +#endif + RemoveRequest(aKey); + + // The priority of the request inside its priority class is defined by + // the page number. This ensures a strict top-to-bottom, left-to-right + // order. + sal_Int32 nPriority (mpCacheContext->GetPriority(aKey)); + Request aRequest (aKey, nPriority, eRequestClass); + mpRequestQueue->insert(aRequest); + + SSCD_SET_REQUEST_CLASS(rRequestData.GetPage(),eRequestClass); + +#ifdef VERBOSE + OSL_TRACE("%s request for page %d with priority class %d", + bRemoved?"replaced":"added", + (rRequestData.GetPage()->GetPageNum()-1)/2, + eRequestClass); +#endif +} + + + + +bool RequestQueue::RemoveRequest ( + CacheKey aKey) +{ + bool bRequestWasRemoved (false); + ::osl::MutexGuard aGuard (maMutex); + + while(true) + { + Container::const_iterator aRequestIterator = ::std::find_if ( + mpRequestQueue->begin(), + mpRequestQueue->end(), + Request::DataComparator(aKey)); + if (aRequestIterator != mpRequestQueue->end()) + { + if (aRequestIterator->mnPriorityInClass == mnMinimumPriority+1) + mnMinimumPriority++; + else if (aRequestIterator->mnPriorityInClass == mnMaximumPriority-1) + mnMaximumPriority--; + mpRequestQueue->erase(aRequestIterator); + bRequestWasRemoved = true; + + if (bRequestWasRemoved) + { + SSCD_SET_STATUS(rRequest.GetPage(),NONE); + } + } + else + break; + } + + return bRequestWasRemoved; +} + + + + +void RequestQueue::ChangeClass ( + CacheKey aKey, + RequestPriorityClass eNewRequestClass) +{ + ::osl::MutexGuard aGuard (maMutex); + + OSL_ASSERT(eNewRequestClass>=MIN__CLASS && eNewRequestClass<=MAX__CLASS); + + Container::const_iterator iRequest ( + ::std::find_if ( + mpRequestQueue->begin(), + mpRequestQueue->end(), + Request::DataComparator(aKey))); + if (iRequest!=mpRequestQueue->end() && iRequest->meClass!=eNewRequestClass) + { + AddRequest(aKey, eNewRequestClass, true); + SSCD_SET_REQUEST_CLASS(rRequestData.GetPage(),eNewRequestClass); + } +} + + + + +CacheKey RequestQueue::GetFront (void) +{ + ::osl::MutexGuard aGuard (maMutex); + + if (mpRequestQueue->empty()) + throw ::com::sun::star::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "RequestQueue::GetFront(): queue is empty")), + NULL); + + return mpRequestQueue->begin()->maKey; +} + + + + +RequestPriorityClass RequestQueue::GetFrontPriorityClass (void) +{ + ::osl::MutexGuard aGuard (maMutex); + + if (mpRequestQueue->empty()) + throw ::com::sun::star::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "RequestQueue::GetFrontPriorityClass(): queue is empty")), + NULL); + + return mpRequestQueue->begin()->meClass; +} + + + + +void RequestQueue::PopFront (void) +{ + ::osl::MutexGuard aGuard (maMutex); + + if ( ! mpRequestQueue->empty()) + { + SSCD_SET_STATUS(maRequestQueue.begin()->mpData->GetPage(),NONE); + + mpRequestQueue->erase(mpRequestQueue->begin()); + + // Reset the priority counter if possible. + if (mpRequestQueue->empty()) + { + mnMinimumPriority = 0; + mnMaximumPriority = 1; + } + } +} + + + + +bool RequestQueue::IsEmpty (void) +{ + ::osl::MutexGuard aGuard (maMutex); + return mpRequestQueue->empty(); +} + + + + +void RequestQueue::Clear (void) +{ + ::osl::MutexGuard aGuard (maMutex); + + mpRequestQueue->clear(); + mnMinimumPriority = 0; + mnMaximumPriority = 1; +} + + + + +::osl::Mutex& RequestQueue::GetMutex (void) +{ + return maMutex; +} + + +} } } // end of namespace ::sd::slidesorter::cache + + + |