comparison 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
comparison
equal deleted inserted replaced
0:decac5df19c4 1:d5d3cb00556a
1 /**
2 * Advanced authorization plugin for Orthanc
3 * Copyright (C) 2017 Osimis, Belgium
4 *
5 * This program is free software: you can redistribute it and/or
6 * modify it under the terms of the GNU Affero General Public License
7 * as published by the Free Software Foundation, either version 3 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 **/
18
19 #include "MemoryCache.h"
20
21 namespace OrthancPlugins
22 {
23 class MemoryCache::Payload : public boost::noncopyable
24 {
25 private:
26 bool hasExpiration_;
27 boost::posix_time::ptime expiration_;
28 std::string value_;
29
30 public:
31 Payload(const std::string& value,
32 unsigned int validity) :
33 value_(value)
34 {
35 if (validity == 0)
36 {
37 hasExpiration_ = false;
38 }
39 else
40 {
41 hasExpiration_ = true;
42 expiration_ = (boost::posix_time::second_clock::local_time() +
43 boost::posix_time::seconds(validity));
44 }
45 }
46
47 bool HasExpired() const
48 {
49 return (hasExpiration_ &&
50 boost::posix_time::second_clock::local_time() >= expiration_);
51 }
52
53 bool GetValue(std::string& target) const
54 {
55 if (HasExpired())
56 {
57 return false;
58 }
59 else
60 {
61 target = value_;
62 return true;
63 }
64 }
65 };
66
67
68 void MemoryCache::RemoveOldest()
69 {
70 Payload* payload = NULL;
71 index_.RemoveOldest(payload);
72 assert(payload != NULL);
73 delete payload;
74 }
75
76
77 void MemoryCache::InvalidateInternal(const std::string& key)
78 {
79 Payload* payload = NULL;
80
81 if (index_.Contains(key, payload))
82 {
83 assert(payload != NULL);
84 delete payload;
85 index_.Invalidate(key);
86 }
87 }
88
89
90 MemoryCache::MemoryCache(unsigned int maxSize) :
91 maxSize_(maxSize)
92 {
93 if (maxSize_ == 0)
94 {
95 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
96 }
97 }
98
99
100 MemoryCache::~MemoryCache()
101 {
102 while (!index_.IsEmpty())
103 {
104 RemoveOldest();
105 }
106 }
107
108
109 void MemoryCache::Invalidate(const std::string& key)
110 {
111 boost::mutex::scoped_lock lock(mutex_);
112 InvalidateInternal(key);
113 }
114
115
116 void MemoryCache::Store(const std::string& key,
117 const std::string& value,
118 unsigned int expiration /* in seconds */)
119 {
120 boost::mutex::scoped_lock lock(mutex_);
121
122 InvalidateInternal(key);
123
124 if (index_.GetSize() == maxSize_)
125 {
126 // The cache is full: Make some room
127 RemoveOldest();
128 }
129
130 index_.Add(key, new Payload(value, expiration));
131 }
132
133
134 bool MemoryCache::Retrieve(std::string& value,
135 const std::string& key)
136 {
137 boost::mutex::scoped_lock lock(mutex_);
138
139 Payload* payload = NULL;
140
141 if (!index_.Contains(key, payload))
142 {
143 return false;
144 }
145
146 assert(payload != NULL);
147
148 if (payload->GetValue(value))
149 {
150 index_.MakeMostRecent(key);
151 return true;
152 }
153 else
154 {
155 // The value has expired in the cache: Invalidate it
156 delete payload;
157 index_.Invalidate(key);
158 return false;
159 }
160 }
161 }