Mercurial > hg > orthanc-authorization
diff Plugin/MemoryCache.cpp @ 1:d5d3cb00556a
initial release
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 22 Mar 2017 16:13:52 +0100 |
parents | |
children | c304ffca5d80 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugin/MemoryCache.cpp Wed Mar 22 16:13:52 2017 +0100 @@ -0,0 +1,161 @@ +/** + * Advanced authorization plugin for Orthanc + * Copyright (C) 2017 Osimis, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#include "MemoryCache.h" + +namespace OrthancPlugins +{ + class MemoryCache::Payload : public boost::noncopyable + { + private: + bool hasExpiration_; + boost::posix_time::ptime expiration_; + std::string value_; + + public: + Payload(const std::string& value, + unsigned int validity) : + value_(value) + { + if (validity == 0) + { + hasExpiration_ = false; + } + else + { + hasExpiration_ = true; + expiration_ = (boost::posix_time::second_clock::local_time() + + boost::posix_time::seconds(validity)); + } + } + + bool HasExpired() const + { + return (hasExpiration_ && + boost::posix_time::second_clock::local_time() >= expiration_); + } + + bool GetValue(std::string& target) const + { + if (HasExpired()) + { + return false; + } + else + { + target = value_; + return true; + } + } + }; + + + void MemoryCache::RemoveOldest() + { + Payload* payload = NULL; + index_.RemoveOldest(payload); + assert(payload != NULL); + delete payload; + } + + + void MemoryCache::InvalidateInternal(const std::string& key) + { + Payload* payload = NULL; + + if (index_.Contains(key, payload)) + { + assert(payload != NULL); + delete payload; + index_.Invalidate(key); + } + } + + + MemoryCache::MemoryCache(unsigned int maxSize) : + maxSize_(maxSize) + { + if (maxSize_ == 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + + MemoryCache::~MemoryCache() + { + while (!index_.IsEmpty()) + { + RemoveOldest(); + } + } + + + void MemoryCache::Invalidate(const std::string& key) + { + boost::mutex::scoped_lock lock(mutex_); + InvalidateInternal(key); + } + + + void MemoryCache::Store(const std::string& key, + const std::string& value, + unsigned int expiration /* in seconds */) + { + boost::mutex::scoped_lock lock(mutex_); + + InvalidateInternal(key); + + if (index_.GetSize() == maxSize_) + { + // The cache is full: Make some room + RemoveOldest(); + } + + index_.Add(key, new Payload(value, expiration)); + } + + + bool MemoryCache::Retrieve(std::string& value, + const std::string& key) + { + boost::mutex::scoped_lock lock(mutex_); + + Payload* payload = NULL; + + if (!index_.Contains(key, payload)) + { + return false; + } + + assert(payload != NULL); + + if (payload->GetValue(value)) + { + index_.MakeMostRecent(key); + return true; + } + else + { + // The value has expired in the cache: Invalidate it + delete payload; + index_.Invalidate(key); + return false; + } + } +}