PLaSK library

Loading...
Searching...
No Matches
cache.hpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2022 Lodz University of Technology
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef PLASK__UTILS_CACHE_H
15#define PLASK__UTILS_CACHE_H
16
21#include <map>
22#include "../memory.hpp"
23
24 namespace plask {
25
35 template <typename Key, typename ValuePtr>
36 struct CacheRemoveStrategyBase {
37
39 std::map<Key*, ValuePtr> map;
40
41};
42
48 template <typename Key, typename ValuePtr>
49 struct CacheRemoveOnlyWhenDeleted: public CacheRemoveStrategyBase<Key, ValuePtr> {
50
52 void onEvent(typename Key::Event& evt) {
53 if (evt.isDelete()) this->map.erase(&evt.source());
54 }
55
56};
57
63 template <typename Key, typename ValuePtr>
64 struct CacheRemoveOnEachChange: public CacheRemoveStrategyBase<Key, ValuePtr> {
65
67 void onEvent(typename Key::Event& evt) {
68 auto* src = evt.source();
69 src->changedDisconnectMethod(this, &CacheRemoveOnEachChange::onEvent);
70 this->map.erase(src);
71 }
72
73};
74
75 template <typename Key, typename ValuePtr, template<typename SKey, typename SValuePtr> class DeleteStrategy = CacheRemoveOnlyWhenDeleted >
76 struct CacheBase: public DeleteStrategy<Key, ValuePtr> {
77
78 typedef typename ValuePtr::element_type Value;
79
81 ~CacheBase() {
82 clear();
83 }
84
90 void append(Key* index, ValuePtr value) {
91 this->map[index] = value;
92 // index->changed.at_front(boost::bind(method, obj, _1));
93 index->changedConnectMethod(this, &DeleteStrategy<Key, ValuePtr>::onEvent, boost::signals2::at_front);
94 }
95
101 void append(plask::shared_ptr<Key> index, ValuePtr value) {
102 append(index.get(), value);
103 }
104
120 plask::shared_ptr<Value> operator()(Key* index, Value* value) {
121 plask::shared_ptr<Value> result(value);
122 this->append(index, result);
123 return result;
124 }
125
141 plask::shared_ptr<Value> operator()(Key* index, shared_ptr<Value> value) {
142 this->append(index, value);
143 return value;
144 }
145
161 plask::shared_ptr<Value> operator()(plask::shared_ptr<Key> index, Value* value) {
162 plask::shared_ptr<Value> result(value);
163 this->append(index, result);
164 return result;
165 }
166
182 plask::shared_ptr<Value> operator()(plask::shared_ptr<Key> index, shared_ptr<Value> value) {
183 this->append(index, value);
184 return value;
185 }
186
190 void clear() {
191 for (auto i: this->map)
192 i.first->changedDisconnectMethod(this, &DeleteStrategy<Key, ValuePtr>::onEvent);
193 this->map.clear();
194 }
195
196};
197
210 template <typename Key, typename Value, template<typename SKey, typename SValuePtr> class DeleteStrategy = CacheRemoveOnlyWhenDeleted >
211 struct WeakCache: public CacheBase<Key, plask::weak_ptr<Value>, DeleteStrategy> {
212
220 plask::shared_ptr<Value> get(Key* index) {
221 auto iter = this->map.find(index);
222 if (iter != this->map.end()) {
223 if (auto res = iter->second.lock())
224 return res;
225 else {
226 iter->first->changedDisconnectMethod(this, &DeleteStrategy<Key, plask::weak_ptr<Value> >::onEvent);
227 this->map.erase(iter);
228 }
229 }
230 return plask::shared_ptr<Value>();
231 }
232
240 plask::shared_ptr<Value> get(plask::shared_ptr<Key> index) {
241 return get(index.get());
242 }
243
249 plask::shared_ptr<Value> get(Key* index) const {
250 auto constr_iter = this->map.find(index);
251 if (constr_iter != this->map.end()) {
252 if (auto res = constr_iter->second.lock())
253 return res;
254 }
255 return plask::shared_ptr<Value>();
256 }
257
263 plask::shared_ptr<Value> get(plask::shared_ptr<Key> index) const {
264 return get(index.get());
265 }
266
272 void cleanDeleted() {
273 for(auto i = this->map.begin(); i != this->map.end(); )
274 if (i->second.expired()) {
275 i->first.changedDisconnectMethod(this, &DeleteStrategy<Key, plask::weak_ptr<Value> >::onEvent);
276 this->map.erase(i++);
277 }
278 else ++i;
279 }
280
281};
282
295 template <typename Key, typename Value, template<typename SKey, typename SValuePtr> class DeleteStrategy = CacheRemoveOnlyWhenDeleted >
296 struct StrongCache: public CacheBase<Key, plask::shared_ptr<Value>, DeleteStrategy> {
297
303 plask::shared_ptr<Value> get(Key* index) const {
304 auto iter = this->map.find(index);
305 return iter != this->map.end() ? iter->second : plask::shared_ptr<Value>();
306 }
307
313 plask::shared_ptr<Value> get(plask::shared_ptr<Key> index) const {
314 return get(index.get());
315 }
316
317};
318
319} // namespace plask
320
321
322#endif // CACHE_H