forked from kovacsv/VisualScriptEngineWeb
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNE_Cache.hpp
More file actions
131 lines (106 loc) · 2.85 KB
/
NE_Cache.hpp
File metadata and controls
131 lines (106 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#ifndef NE_CACHE_HPP
#define NE_CACHE_HPP
#include <list>
#include <unordered_map>
namespace NE
{
template <typename KeyType, typename ValueType>
class Cache
{
public:
class Controller
{
public:
Controller ();
virtual ~Controller ();
virtual ValueType CreateValue (const KeyType& key) = 0;
virtual void DisposeValue (ValueType& value) = 0;
};
Cache (size_t maxSize);
Cache (size_t maxSize, Controller* controller);
Cache (const Cache& rhs) = delete;
virtual ~Cache ();
Cache& operator= (const Cache& rhs) = delete;
bool Contains (const KeyType& key) const;
void Clear ();
bool Add (const KeyType& key, const ValueType& value);
const ValueType& Get (const KeyType& key);
private:
using KeyValuePair = std::pair<KeyType, ValueType>;
using KeyValuePairIterator = typename std::list<KeyValuePair>::iterator;
size_t maxSize;
Controller* controller;
std::list<KeyValuePair> valueList;
std::unordered_map<KeyType, KeyValuePairIterator> valueMap;
};
template <typename KeyType, typename ValueType>
Cache<KeyType, ValueType>::Controller::Controller ()
{
}
template <typename KeyType, typename ValueType>
Cache<KeyType, ValueType>::Controller::~Controller ()
{
}
template <typename KeyType, typename ValueType>
Cache<KeyType, ValueType>::Cache (size_t maxSize) :
Cache (maxSize, nullptr)
{
}
template <typename KeyType, typename ValueType>
Cache<KeyType, ValueType>::Cache (size_t maxSize, Controller* controller) :
maxSize (maxSize),
controller (controller),
valueList (),
valueMap ()
{
}
template <typename KeyType, typename ValueType>
Cache<KeyType, ValueType>::~Cache ()
{
Clear ();
}
template <typename KeyType, typename ValueType>
bool Cache<KeyType, ValueType>::Contains (const KeyType& key) const
{
return valueMap.find (key) != valueMap.end ();
}
template <typename KeyType, typename ValueType>
void Cache<KeyType, ValueType>::Clear ()
{
if (controller != nullptr) {
for (KeyValuePair& it : valueList) {
controller->DisposeValue (it.second);
}
}
valueList.clear ();
valueMap.clear ();
}
template <typename KeyType, typename ValueType>
bool Cache<KeyType, ValueType>::Add (const KeyType& key, const ValueType& value)
{
if (Contains (key)) {
return false;
}
if (valueList.size () >= maxSize) {
KeyValuePair& keyValuePair = valueList.front ();
if (controller != nullptr) {
controller->DisposeValue (keyValuePair.second);
}
valueMap.erase (keyValuePair.first);
valueList.pop_front ();
}
valueList.push_back ({ key, value });
valueMap.insert ({ key, std::prev (valueList.end ()) });
return true;
}
template <typename KeyType, typename ValueType>
const ValueType& Cache<KeyType, ValueType>::Get (const KeyType& key)
{
if (controller != nullptr && !Contains (key)) {
Add (key, controller->CreateValue (key));
}
const KeyValuePair& pair = *valueMap.at (key);
return pair.second;
}
}
#endif