Fabcoin Core  0.16.2
P2P Digital Currency
MemoryDB.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum 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  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include "Common.h"
23 #include "MemoryDB.h"
24 using namespace std;
25 using namespace dev;
26 
27 namespace dev
28 {
29 
30 const char* DBChannel::name() { return "TDB"; }
31 const char* DBWarn::name() { return "TDB"; }
32 
33 std::unordered_map<h256, std::string> MemoryDB::get() const
34 {
35 #if DEV_GUARDED_DB
36  ReadGuard l(x_this);
37 #endif
38  std::unordered_map<h256, std::string> ret;
39  for (auto const& i: m_main)
40  if (!m_enforceRefs || i.second.second > 0)
41  ret.insert(make_pair(i.first, i.second.first));
42  return ret;
43 }
44 
45 MemoryDB& MemoryDB::operator=(MemoryDB const& _c)
46 {
47  if (this == &_c)
48  return *this;
49 #if DEV_GUARDED_DB
50  ReadGuard l(_c.x_this);
51  WriteGuard l2(x_this);
52 #endif
53  m_main = _c.m_main;
54  m_aux = _c.m_aux;
55  return *this;
56 }
57 
58 std::string MemoryDB::lookup(h256 const& _h) const
59 {
60 #if DEV_GUARDED_DB
61  ReadGuard l(x_this);
62 #endif
63  auto it = m_main.find(_h);
64  if (it != m_main.end())
65  {
66  if (!m_enforceRefs || it->second.second > 0)
67  return it->second.first;
68  else
69  cwarn << "Lookup required for value with refcount == 0. This is probably a critical trie issue" << _h;
70  }
71  return std::string();
72 }
73 
74 bool MemoryDB::exists(h256 const& _h) const
75 {
76 #if DEV_GUARDED_DB
77  ReadGuard l(x_this);
78 #endif
79  auto it = m_main.find(_h);
80  if (it != m_main.end() && (!m_enforceRefs || it->second.second > 0))
81  return true;
82  return false;
83 }
84 
85 void MemoryDB::insert(h256 const& _h, bytesConstRef _v)
86 {
87 #if DEV_GUARDED_DB
88  WriteGuard l(x_this);
89 #endif
90  auto it = m_main.find(_h);
91  if (it != m_main.end())
92  {
93  it->second.first = _v.toString();
94  it->second.second++;
95  }
96  else
97  m_main[_h] = make_pair(_v.toString(), 1);
98 #if ETH_PARANOIA
99  dbdebug << "INST" << _h << "=>" << m_main[_h].second;
100 #endif
101 }
102 
103 bool MemoryDB::kill(h256 const& _h)
104 {
105 #if DEV_GUARDED_DB
106  ReadGuard l(x_this);
107 #endif
108  if (m_main.count(_h))
109  {
110  if (m_main[_h].second > 0)
111  {
112  m_main[_h].second--;
113  return true;
114  }
115 #if ETH_PARANOIA
116  else
117  {
118  // If we get to this point, then there was probably a node in the level DB which we need to remove and which we have previously
119  // used as part of the memory-based MemoryDB. Nothing to be worried about *as long as the node exists in the DB*.
120  dbdebug << "NOKILL-WAS" << _h;
121  }
122  dbdebug << "KILL" << _h << "=>" << m_main[_h].second;
123  }
124  else
125  {
126  dbdebug << "NOKILL" << _h;
127 #endif
128  }
129  return false;
130 }
131 
132 bytes MemoryDB::lookupAux(h256 const& _h) const
133 {
134 #if DEV_GUARDED_DB
135  ReadGuard l(x_this);
136 #endif
137  auto it = m_aux.find(_h);
138  if (it != m_aux.end() && (!m_enforceRefs || it->second.second))
139  return it->second.first;
140  return bytes();
141 }
142 
143 void MemoryDB::removeAux(h256 const& _h)
144 {
145 #if DEV_GUARDED_DB
146  WriteGuard l(x_this);
147 #endif
148  m_aux[_h].second = false;
149 }
150 
151 void MemoryDB::insertAux(h256 const& _h, bytesConstRef _v)
152 {
153 #if DEV_GUARDED_DB
154  WriteGuard l(x_this);
155 #endif
156  m_aux[_h] = make_pair(_v.toBytes(), true);
157 }
158 
159 void MemoryDB::purge()
160 {
161 #if DEV_GUARDED_DB
162  WriteGuard l(x_this);
163 #endif
164  // purge m_main
165  for (auto it = m_main.begin(); it != m_main.end(); )
166  if (it->second.second)
167  ++it;
168  else
169  it = m_main.erase(it);
170 
171  // purge m_aux
172  for (auto it = m_aux.begin(); it != m_aux.end(); )
173  if (it->second.second)
174  ++it;
175  else
176  it = m_aux.erase(it);
177 }
178 
179 h256Hash MemoryDB::keys() const
180 {
181 #if DEV_GUARDED_DB
182  ReadGuard l(x_this);
183 #endif
184  h256Hash ret;
185  for (auto const& i: m_main)
186  if (i.second.second)
187  ret.insert(i.first);
188  return ret;
189 }
190 
191 }
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
std::unordered_map< h256, std::pair< std::string, unsigned > > m_main
Definition: MemoryDB.h:70
#define dbdebug
Definition: MemoryDB.h:38
std::hash for asio::adress
Definition: Common.h:323
const char * name
Definition: rest.cpp:36
std::vector< byte > bytes
Definition: Common.h:75
std::vector< unsigned char > toBytes() const
Definition: vector_ref.h:45
#define cwarn
Definition: Log.h:304
boost::shared_lock< boost::shared_mutex > ReadGuard
Definition: Guards.h:44
boost::unique_lock< boost::shared_mutex > WriteGuard
Definition: Guards.h:47
std::unordered_set< h256 > h256Hash
Definition: FixedHash.h:349
std::unordered_map< h256, std::pair< bytes, bool > > m_aux
Definition: MemoryDB.h:71
std::string toString() const
Definition: vector_ref.h:46