MemoryDB.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file MemoryDB.cpp
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #include "Common.h"
  19. #include "MemoryDB.h"
  20. using namespace std;
  21. using namespace dev;
  22. namespace dev
  23. {
  24. const char* DBChannel::name() { return "TDB"; }
  25. const char* DBWarn::name() { return "TDB"; }
  26. std::unordered_map<h256, std::string> MemoryDB::get() const
  27. {
  28. #if DEV_GUARDED_DB
  29. ReadGuard l(x_this);
  30. #endif
  31. std::unordered_map<h256, std::string> ret;
  32. for (auto const& i: m_main)
  33. if (!m_enforceRefs || i.second.second > 0)
  34. ret.insert(make_pair(i.first, i.second.first));
  35. return ret;
  36. }
  37. MemoryDB& MemoryDB::operator=(MemoryDB const& _c)
  38. {
  39. if (this == &_c)
  40. return *this;
  41. #if DEV_GUARDED_DB
  42. ReadGuard l(_c.x_this);
  43. WriteGuard l2(x_this);
  44. #endif
  45. m_main = _c.m_main;
  46. m_aux = _c.m_aux;
  47. return *this;
  48. }
  49. std::string MemoryDB::lookup(h256 const& _h) const
  50. {
  51. #if DEV_GUARDED_DB
  52. ReadGuard l(x_this);
  53. #endif
  54. auto it = m_main.find(_h);
  55. if (it != m_main.end())
  56. {
  57. if (!m_enforceRefs || it->second.second > 0)
  58. return it->second.first;
  59. else
  60. cwarn << "Lookup required for value with refcount == 0. This is probably a critical trie issue" << _h;
  61. }
  62. return std::string();
  63. }
  64. bool MemoryDB::exists(h256 const& _h) const
  65. {
  66. #if DEV_GUARDED_DB
  67. ReadGuard l(x_this);
  68. #endif
  69. auto it = m_main.find(_h);
  70. if (it != m_main.end() && (!m_enforceRefs || it->second.second > 0))
  71. return true;
  72. return false;
  73. }
  74. void MemoryDB::insert(h256 const& _h, bytesConstRef _v)
  75. {
  76. #if DEV_GUARDED_DB
  77. WriteGuard l(x_this);
  78. #endif
  79. auto it = m_main.find(_h);
  80. if (it != m_main.end())
  81. {
  82. it->second.first = _v.toString();
  83. it->second.second++;
  84. }
  85. else
  86. m_main[_h] = make_pair(_v.toString(), 1);
  87. #if ETH_PARANOIA
  88. dbdebug << "INST" << _h << "=>" << m_main[_h].second;
  89. #endif
  90. }
  91. bool MemoryDB::kill(h256 const& _h)
  92. {
  93. #if DEV_GUARDED_DB
  94. ReadGuard l(x_this);
  95. #endif
  96. if (m_main.count(_h))
  97. {
  98. if (m_main[_h].second > 0)
  99. {
  100. m_main[_h].second--;
  101. return true;
  102. }
  103. #if ETH_PARANOIA
  104. else
  105. {
  106. // 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
  107. // used as part of the memory-based MemoryDB. Nothing to be worried about *as long as the node exists in the DB*.
  108. dbdebug << "NOKILL-WAS" << _h;
  109. }
  110. dbdebug << "KILL" << _h << "=>" << m_main[_h].second;
  111. }
  112. else
  113. {
  114. dbdebug << "NOKILL" << _h;
  115. #endif
  116. }
  117. return false;
  118. }
  119. bytes MemoryDB::lookupAux(h256 const& _h) const
  120. {
  121. #if DEV_GUARDED_DB
  122. ReadGuard l(x_this);
  123. #endif
  124. auto it = m_aux.find(_h);
  125. if (it != m_aux.end() && (!m_enforceRefs || it->second.second))
  126. return it->second.first;
  127. return bytes();
  128. }
  129. void MemoryDB::removeAux(h256 const& _h)
  130. {
  131. #if DEV_GUARDED_DB
  132. WriteGuard l(x_this);
  133. #endif
  134. m_aux[_h].second = false;
  135. }
  136. void MemoryDB::insertAux(h256 const& _h, bytesConstRef _v)
  137. {
  138. #if DEV_GUARDED_DB
  139. WriteGuard l(x_this);
  140. #endif
  141. m_aux[_h] = make_pair(_v.toBytes(), true);
  142. }
  143. void MemoryDB::purge()
  144. {
  145. #if DEV_GUARDED_DB
  146. WriteGuard l(x_this);
  147. #endif
  148. // purge m_main
  149. for (auto it = m_main.begin(); it != m_main.end(); )
  150. if (it->second.second)
  151. ++it;
  152. else
  153. it = m_main.erase(it);
  154. // purge m_aux
  155. for (auto it = m_aux.begin(); it != m_aux.end(); )
  156. if (it->second.second)
  157. ++it;
  158. else
  159. it = m_aux.erase(it);
  160. }
  161. h256Hash MemoryDB::keys() const
  162. {
  163. #if DEV_GUARDED_DB
  164. ReadGuard l(x_this);
  165. #endif
  166. h256Hash ret;
  167. for (auto const& i: m_main)
  168. if (i.second.second)
  169. ret.insert(i.first);
  170. return ret;
  171. }
  172. }