Dash Core  0.12.2.1
P2P Digital Currency
cachemultimap.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2017 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef CACHEMULTIMAP_H_
6 #define CACHEMULTIMAP_H_
7 
8 #include <cstddef>
9 #include <map>
10 #include <list>
11 #include <set>
12 
13 #include "serialize.h"
14 
15 #include "cachemap.h"
16 
20 template<typename K, typename V, typename Size = uint32_t>
22 {
23 public:
24  typedef Size size_type;
25 
27 
28  typedef std::list<item_t> list_t;
29 
30  typedef typename list_t::iterator list_it;
31 
32  typedef typename list_t::const_iterator list_cit;
33 
34  typedef std::map<V,list_it> it_map_t;
35 
36  typedef typename it_map_t::iterator it_map_it;
37 
38  typedef typename it_map_t::const_iterator it_map_cit;
39 
40  typedef std::map<K, it_map_t> map_t;
41 
42  typedef typename map_t::iterator map_it;
43 
44  typedef typename map_t::const_iterator map_cit;
45 
46 private:
48 
50 
52 
54 
55 public:
56  CacheMultiMap(size_type nMaxSizeIn = 0)
57  : nMaxSize(nMaxSizeIn),
58  nCurrentSize(0),
59  listItems(),
60  mapIndex()
61  {}
62 
64  : nMaxSize(other.nMaxSize),
66  listItems(other.listItems),
67  mapIndex()
68  {
69  RebuildIndex();
70  }
71 
72  void Clear()
73  {
74  mapIndex.clear();
75  listItems.clear();
76  nCurrentSize = 0;
77  }
78 
79  void SetMaxSize(size_type nMaxSizeIn)
80  {
81  nMaxSize = nMaxSizeIn;
82  }
83 
85  return nMaxSize;
86  }
87 
88  size_type GetSize() const {
89  return nCurrentSize;
90  }
91 
92  bool Insert(const K& key, const V& value)
93  {
94  if(nCurrentSize == nMaxSize) {
95  PruneLast();
96  }
97  map_it mit = mapIndex.find(key);
98  if(mit == mapIndex.end()) {
99  mit = mapIndex.insert(std::pair<K,it_map_t>(key, it_map_t())).first;
100  }
101  it_map_t& mapIt = mit->second;
102 
103  if(mapIt.count(value) > 0) {
104  // Don't insert duplicates
105  return false;
106  }
107 
108  listItems.push_front(item_t(key, value));
109  list_it lit = listItems.begin();
110 
111  mapIt[value] = lit;
112  ++nCurrentSize;
113  return true;
114  }
115 
116  bool HasKey(const K& key) const
117  {
118  map_cit it = mapIndex.find(key);
119  return (it != mapIndex.end());
120  }
121 
122  bool Get(const K& key, V& value) const
123  {
124  map_cit it = mapIndex.find(key);
125  if(it == mapIndex.end()) {
126  return false;
127  }
128  const it_map_t& mapIt = it->second;
129  const item_t& item = *(mapIt.begin()->second);
130  value = item.value;
131  return true;
132  }
133 
134  bool GetAll(const K& key, std::vector<V>& vecValues)
135  {
136  map_cit mit = mapIndex.find(key);
137  if(mit == mapIndex.end()) {
138  return false;
139  }
140  const it_map_t& mapIt = mit->second;
141 
142  for(it_map_cit it = mapIt.begin(); it != mapIt.end(); ++it) {
143  const item_t& item = *(it->second);
144  vecValues.push_back(item.value);
145  }
146  return true;
147  }
148 
149  void GetKeys(std::vector<K>& vecKeys)
150  {
151  for(map_cit it = mapIndex.begin(); it != mapIndex.end(); ++it) {
152  vecKeys.push_back(it->first);
153  }
154  }
155 
156  void Erase(const K& key)
157  {
158  map_it mit = mapIndex.find(key);
159  if(mit == mapIndex.end()) {
160  return;
161  }
162  it_map_t& mapIt = mit->second;
163 
164  for(it_map_it it = mapIt.begin(); it != mapIt.end(); ++it) {
165  listItems.erase(it->second);
166  --nCurrentSize;
167  }
168 
169  mapIndex.erase(mit);
170  }
171 
172  void Erase(const K& key, const V& value)
173  {
174  map_it mit = mapIndex.find(key);
175  if(mit == mapIndex.end()) {
176  return;
177  }
178  it_map_t& mapIt = mit->second;
179 
180  it_map_it it = mapIt.find(value);
181  if(it == mapIt.end()) {
182  return;
183  }
184 
185  listItems.erase(it->second);
186  --nCurrentSize;
187  mapIt.erase(it);
188 
189  if(mapIt.size() < 1) {
190  mapIndex.erase(mit);
191  }
192  }
193 
194  const list_t& GetItemList() const {
195  return listItems;
196  }
197 
199  {
200  nMaxSize = other.nMaxSize;
201  nCurrentSize = other.nCurrentSize;
202  listItems = other.listItems;
203  RebuildIndex();
204  return *this;
205  }
206 
208 
209  template <typename Stream, typename Operation>
210  inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
211  {
215  if(ser_action.ForRead()) {
216  RebuildIndex();
217  }
218  }
219 
220 private:
221  void PruneLast()
222  {
223  if(nCurrentSize < 1) {
224  return;
225  }
226 
227  list_it lit = listItems.end();
228  --lit;
229  item_t& item = *lit;
230 
231  map_it mit = mapIndex.find(item.key);
232 
233  if(mit != mapIndex.end()) {
234  it_map_t& mapIt = mit->second;
235 
236  mapIt.erase(item.value);
237 
238  if(mapIt.size() < 1) {
239  mapIndex.erase(item.key);
240  }
241  }
242 
243  listItems.pop_back();
244  --nCurrentSize;
245  }
246 
248  {
249  mapIndex.clear();
250  for(list_it lit = listItems.begin(); lit != listItems.end(); ++lit) {
251  item_t& item = *lit;
252  map_it mit = mapIndex.find(item.key);
253  if(mit == mapIndex.end()) {
254  mit = mapIndex.insert(std::pair<K,it_map_t>(item.key, it_map_t())).first;
255  }
256  it_map_t& mapIt = mit->second;
257  mapIt[item.value] = lit;
258  }
259  }
260 };
261 
262 #endif /* CACHEMULTIMAP_H_ */
size_type GetSize() const
Definition: cachemultimap.h:88
void RebuildIndex()
map_t::iterator map_it
Definition: cachemultimap.h:42
#define READWRITE(obj)
Definition: serialize.h:175
bool Insert(const K &key, const V &value)
Definition: cachemultimap.h:92
std::map< K, it_map_t > map_t
Definition: cachemultimap.h:40
map_t::const_iterator map_cit
Definition: cachemultimap.h:44
void Erase(const K &key)
std::map< V, list_it > it_map_t
Definition: cachemultimap.h:34
size_type nMaxSize
Definition: cachemap.h:66
bool Get(const K &key, V &value) const
const list_t & GetItemList() const
size_type nMaxSize
Definition: cachemultimap.h:47
void GetKeys(std::vector< K > &vecKeys)
CacheItem< K, V > item_t
Definition: cachemultimap.h:26
bool HasKey(const K &key) const
it_map_t::const_iterator it_map_cit
Definition: cachemultimap.h:38
size_type GetMaxSize() const
Definition: cachemultimap.h:84
list_t::const_iterator list_cit
Definition: cachemultimap.h:32
void SetMaxSize(size_type nMaxSizeIn)
Definition: cachemultimap.h:79
CacheMultiMap(size_type nMaxSizeIn=0)
Definition: cachemultimap.h:56
it_map_t::iterator it_map_it
Definition: cachemultimap.h:36
size_type nCurrentSize
Definition: cachemultimap.h:49
std::list< item_t > list_t
Definition: cachemultimap.h:28
list_t listItems
Definition: cachemultimap.h:51
size_type nCurrentSize
Definition: cachemap.h:68
bool GetAll(const K &key, std::vector< V > &vecValues)
CacheMap< K, V > & operator=(const CacheMap< K, V > &other)
void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)
list_t listItems
Definition: cachemap.h:70
void Erase(const K &key, const V &value)
list_t::iterator list_it
Definition: cachemultimap.h:30
CacheMultiMap(const CacheMap< K, V > &other)
Definition: cachemultimap.h:63