MemTrie.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  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 MemTrie.cpp
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #include "MemTrie.h"
  19. #include <libdevcore/TrieCommon.h>
  20. #include <libdevcore/SHA3.h>
  21. using namespace std;
  22. using namespace dev;
  23. namespace dev
  24. {
  25. #define ENABLE_DEBUG_PRINT 0
  26. /*/
  27. #define APPEND_CHILD appendData
  28. /*/
  29. #define APPEND_CHILD appendRaw
  30. /**/
  31. class MemTrieNode
  32. {
  33. public:
  34. MemTrieNode() {}
  35. virtual ~MemTrieNode() {}
  36. virtual std::string const& at(bytesConstRef _key) const = 0;
  37. virtual MemTrieNode* insert(bytesConstRef _key, std::string const& _value) = 0;
  38. virtual MemTrieNode* remove(bytesConstRef _key) = 0;
  39. void putRLP(RLPStream& _parentStream) const;
  40. #if ENABLE_DEBUG_PRINT
  41. void debugPrint(std::string const& _indent = "") const { std::cerr << std::hex << hash256() << ":" << std::dec << std::endl; debugPrintBody(_indent); }
  42. #endif
  43. /// 256-bit hash of the node - this is a SHA-3/256 hash of the RLP of the node.
  44. h256 hash256() const { RLPStream s; makeRLP(s); return dev::sha3(s.out()); }
  45. bytes rlp() const { RLPStream s; makeRLP(s); return s.out(); }
  46. void mark() { m_hash256 = h256(); }
  47. protected:
  48. virtual void makeRLP(RLPStream& _intoStream) const = 0;
  49. #if ENABLE_DEBUG_PRINT
  50. virtual void debugPrintBody(std::string const& _indent = "") const = 0;
  51. #endif
  52. static MemTrieNode* newBranch(bytesConstRef _k1, std::string const& _v1, bytesConstRef _k2, std::string const& _v2);
  53. private:
  54. mutable h256 m_hash256;
  55. };
  56. static const std::string c_nullString;
  57. class TrieExtNode: public MemTrieNode
  58. {
  59. public:
  60. TrieExtNode(bytesConstRef _bytes): m_ext(_bytes.begin(), _bytes.end()) {}
  61. bytes m_ext;
  62. };
  63. class TrieBranchNode: public MemTrieNode
  64. {
  65. public:
  66. TrieBranchNode(std::string const& _value): m_value(_value)
  67. {
  68. memset(m_nodes.data(), 0, sizeof(MemTrieNode*) * 16);
  69. }
  70. TrieBranchNode(byte _i1, MemTrieNode* _n1, std::string const& _value = std::string()): m_value(_value)
  71. {
  72. memset(m_nodes.data(), 0, sizeof(MemTrieNode*) * 16);
  73. m_nodes[_i1] = _n1;
  74. }
  75. TrieBranchNode(byte _i1, MemTrieNode* _n1, byte _i2, MemTrieNode* _n2)
  76. {
  77. memset(m_nodes.data(), 0, sizeof(MemTrieNode*) * 16);
  78. m_nodes[_i1] = _n1;
  79. m_nodes[_i2] = _n2;
  80. }
  81. virtual ~TrieBranchNode()
  82. {
  83. for (auto i: m_nodes)
  84. delete i;
  85. }
  86. #if ENABLE_DEBUG_PRINT
  87. virtual void debugPrintBody(std::string const& _indent) const
  88. {
  89. if (m_value.size())
  90. std::cerr << _indent << "@: " << m_value << std::endl;
  91. for (auto i = 0; i < 16; ++i)
  92. if (m_nodes[i])
  93. {
  94. std::cerr << _indent << std::hex << i << ": " << std::dec;
  95. m_nodes[i]->debugPrint(_indent + " ");
  96. }
  97. }
  98. #endif
  99. virtual std::string const& at(bytesConstRef _key) const override;
  100. virtual MemTrieNode* insert(bytesConstRef _key, std::string const& _value) override;
  101. virtual MemTrieNode* remove(bytesConstRef _key) override;
  102. virtual void makeRLP(RLPStream& _parentStream) const override;
  103. private:
  104. /// @returns (byte)-1 when no active branches, 16 when multiple active and the index of the active branch otherwise.
  105. byte activeBranch() const;
  106. MemTrieNode* rejig();
  107. std::array<MemTrieNode*, 16> m_nodes;
  108. std::string m_value;
  109. };
  110. class TrieLeafNode: public TrieExtNode
  111. {
  112. public:
  113. TrieLeafNode(bytesConstRef _key, std::string const& _value): TrieExtNode(_key), m_value(_value) {}
  114. #if ENABLE_DEBUG_PRINT
  115. virtual void debugPrintBody(std::string const& _indent) const
  116. {
  117. assert(m_value.size());
  118. std::cerr << _indent;
  119. if (m_ext.size())
  120. std::cerr << toHex(m_ext, 1) << ": ";
  121. else
  122. std::cerr << "@: ";
  123. std::cerr << m_value << std::endl;
  124. }
  125. #endif
  126. virtual std::string const& at(bytesConstRef _key) const override { return contains(_key) ? m_value : c_nullString; }
  127. virtual MemTrieNode* insert(bytesConstRef _key, std::string const& _value) override;
  128. virtual MemTrieNode* remove(bytesConstRef _key) override;
  129. virtual void makeRLP(RLPStream& _parentStream) const override;
  130. private:
  131. bool contains(bytesConstRef _key) const { return _key.size() == m_ext.size() && !memcmp(_key.data(), m_ext.data(), _key.size()); }
  132. std::string m_value;
  133. };
  134. class TrieInfixNode: public TrieExtNode
  135. {
  136. public:
  137. TrieInfixNode(bytesConstRef _key, MemTrieNode* _next): TrieExtNode(_key), m_next(_next) {}
  138. virtual ~TrieInfixNode() { delete m_next; }
  139. #if ENABLE_DEBUG_PRINT
  140. virtual void debugPrintBody(std::string const& _indent) const
  141. {
  142. std::cerr << _indent << toHex(m_ext, 1) << ": ";
  143. m_next->debugPrint(_indent + " ");
  144. }
  145. #endif
  146. virtual std::string const& at(bytesConstRef _key) const override { assert(m_next); return contains(_key) ? m_next->at(_key.cropped(m_ext.size())) : c_nullString; }
  147. virtual MemTrieNode* insert(bytesConstRef _key, std::string const& _value) override;
  148. virtual MemTrieNode* remove(bytesConstRef _key) override;
  149. virtual void makeRLP(RLPStream& _parentStream) const override;
  150. private:
  151. bool contains(bytesConstRef _key) const { return _key.size() >= m_ext.size() && !memcmp(_key.data(), m_ext.data(), m_ext.size()); }
  152. MemTrieNode* m_next;
  153. };
  154. void MemTrieNode::putRLP(RLPStream& _parentStream) const
  155. {
  156. RLPStream s;
  157. makeRLP(s);
  158. if (s.out().size() < 32)
  159. _parentStream.APPEND_CHILD(s.out());
  160. else
  161. _parentStream << dev::sha3(s.out());
  162. }
  163. void TrieBranchNode::makeRLP(RLPStream& _intoStream) const
  164. {
  165. _intoStream.appendList(17);
  166. for (auto i: m_nodes)
  167. if (i)
  168. i->putRLP(_intoStream);
  169. else
  170. _intoStream << "";
  171. _intoStream << m_value;
  172. }
  173. void TrieLeafNode::makeRLP(RLPStream& _intoStream) const
  174. {
  175. _intoStream.appendList(2) << hexPrefixEncode(m_ext, true) << m_value;
  176. }
  177. void TrieInfixNode::makeRLP(RLPStream& _intoStream) const
  178. {
  179. assert(m_next);
  180. _intoStream.appendList(2);
  181. _intoStream << hexPrefixEncode(m_ext, false);
  182. m_next->putRLP(_intoStream);
  183. }
  184. MemTrieNode* MemTrieNode::newBranch(bytesConstRef _k1, std::string const& _v1, bytesConstRef _k2, std::string const& _v2)
  185. {
  186. unsigned prefix = commonPrefix(_k1, _k2);
  187. MemTrieNode* ret;
  188. if (_k1.size() == prefix)
  189. ret = new TrieBranchNode(_k2[prefix], new TrieLeafNode(_k2.cropped(prefix + 1), _v2), _v1);
  190. else if (_k2.size() == prefix)
  191. ret = new TrieBranchNode(_k1[prefix], new TrieLeafNode(_k1.cropped(prefix + 1), _v1), _v2);
  192. else // both continue after split
  193. ret = new TrieBranchNode(_k1[prefix], new TrieLeafNode(_k1.cropped(prefix + 1), _v1), _k2[prefix], new TrieLeafNode(_k2.cropped(prefix + 1), _v2));
  194. if (prefix)
  195. // have shared prefix - split.
  196. ret = new TrieInfixNode(_k1.cropped(0, prefix), ret);
  197. return ret;
  198. }
  199. std::string const& TrieBranchNode::at(bytesConstRef _key) const
  200. {
  201. if (_key.empty())
  202. return m_value;
  203. else if (m_nodes[_key[0]] != nullptr)
  204. return m_nodes[_key[0]]->at(_key.cropped(1));
  205. return c_nullString;
  206. }
  207. MemTrieNode* TrieBranchNode::insert(bytesConstRef _key, std::string const& _value)
  208. {
  209. assert(_value.size());
  210. mark();
  211. if (_key.empty())
  212. m_value = _value;
  213. else
  214. if (!m_nodes[_key[0]])
  215. m_nodes[_key[0]] = new TrieLeafNode(_key.cropped(1), _value);
  216. else
  217. m_nodes[_key[0]] = m_nodes[_key[0]]->insert(_key.cropped(1), _value);
  218. return this;
  219. }
  220. MemTrieNode* TrieBranchNode::remove(bytesConstRef _key)
  221. {
  222. if (_key.empty())
  223. if (m_value.size())
  224. {
  225. m_value.clear();
  226. return rejig();
  227. }
  228. else {}
  229. else if (m_nodes[_key[0]] != nullptr)
  230. {
  231. m_nodes[_key[0]] = m_nodes[_key[0]]->remove(_key.cropped(1));
  232. return rejig();
  233. }
  234. return this;
  235. }
  236. MemTrieNode* TrieBranchNode::rejig()
  237. {
  238. mark();
  239. byte n = activeBranch();
  240. if (n == (byte)-1 && m_value.size())
  241. {
  242. // switch to leaf
  243. auto r = new TrieLeafNode(bytesConstRef(), m_value);
  244. delete this;
  245. return r;
  246. }
  247. else if (n < 16 && m_value.empty())
  248. {
  249. // only branching to n...
  250. if (auto b = dynamic_cast<TrieBranchNode*>(m_nodes[n]))
  251. {
  252. // switch to infix
  253. m_nodes[n] = nullptr;
  254. delete this;
  255. return new TrieInfixNode(bytesConstRef(&n, 1), b);
  256. }
  257. else
  258. {
  259. auto x = dynamic_cast<TrieExtNode*>(m_nodes[n]);
  260. assert(x);
  261. // include in child
  262. pushFront(x->m_ext, n);
  263. m_nodes[n] = nullptr;
  264. delete this;
  265. return x;
  266. }
  267. }
  268. return this;
  269. }
  270. byte TrieBranchNode::activeBranch() const
  271. {
  272. byte n = (byte)-1;
  273. for (int i = 0; i < 16; ++i)
  274. if (m_nodes[i] != nullptr)
  275. {
  276. if (n == (byte)-1)
  277. n = (byte)i;
  278. else
  279. return 16;
  280. }
  281. return n;
  282. }
  283. MemTrieNode* TrieInfixNode::insert(bytesConstRef _key, std::string const& _value)
  284. {
  285. assert(_value.size());
  286. mark();
  287. if (contains(_key))
  288. {
  289. m_next = m_next->insert(_key.cropped(m_ext.size()), _value);
  290. return this;
  291. }
  292. else
  293. {
  294. unsigned prefix = commonPrefix(_key, m_ext);
  295. if (prefix)
  296. {
  297. // one infix becomes two infixes, then insert into the second
  298. // instead of pop_front()...
  299. trimFront(m_ext, prefix);
  300. return new TrieInfixNode(_key.cropped(0, prefix), insert(_key.cropped(prefix), _value));
  301. }
  302. else
  303. {
  304. // split here.
  305. auto f = m_ext[0];
  306. trimFront(m_ext, 1);
  307. MemTrieNode* n = m_ext.empty() ? m_next : this;
  308. if (n != this)
  309. {
  310. m_next = nullptr;
  311. delete this;
  312. }
  313. TrieBranchNode* ret = new TrieBranchNode(f, n);
  314. ret->insert(_key, _value);
  315. return ret;
  316. }
  317. }
  318. }
  319. MemTrieNode* TrieInfixNode::remove(bytesConstRef _key)
  320. {
  321. if (contains(_key))
  322. {
  323. mark();
  324. m_next = m_next->remove(_key.cropped(m_ext.size()));
  325. if (auto p = dynamic_cast<TrieExtNode*>(m_next))
  326. {
  327. // merge with child...
  328. m_ext.reserve(m_ext.size() + p->m_ext.size());
  329. for (auto i: p->m_ext)
  330. m_ext.push_back(i);
  331. p->m_ext = m_ext;
  332. p->mark();
  333. m_next = nullptr;
  334. delete this;
  335. return p;
  336. }
  337. if (!m_next)
  338. {
  339. delete this;
  340. return nullptr;
  341. }
  342. }
  343. return this;
  344. }
  345. MemTrieNode* TrieLeafNode::insert(bytesConstRef _key, std::string const& _value)
  346. {
  347. assert(_value.size());
  348. mark();
  349. if (contains(_key))
  350. {
  351. m_value = _value;
  352. return this;
  353. }
  354. else
  355. {
  356. // create new trie.
  357. auto n = MemTrieNode::newBranch(_key, _value, bytesConstRef(&m_ext), m_value);
  358. delete this;
  359. return n;
  360. }
  361. }
  362. MemTrieNode* TrieLeafNode::remove(bytesConstRef _key)
  363. {
  364. if (contains(_key))
  365. {
  366. delete this;
  367. return nullptr;
  368. }
  369. return this;
  370. }
  371. MemTrie::~MemTrie()
  372. {
  373. delete m_root;
  374. }
  375. h256 MemTrie::hash256() const
  376. {
  377. return m_root ? m_root->hash256() : sha3(dev::rlp(bytesConstRef()));
  378. }
  379. bytes MemTrie::rlp() const
  380. {
  381. return m_root ? m_root->rlp() : dev::rlp(bytesConstRef());
  382. }
  383. void MemTrie::debugPrint()
  384. {
  385. #if ENABLE_DEBUG_PRINT
  386. if (m_root)
  387. m_root->debugPrint();
  388. #endif
  389. }
  390. std::string const& MemTrie::at(std::string const& _key) const
  391. {
  392. if (!m_root)
  393. return c_nullString;
  394. auto h = asNibbles(_key);
  395. return m_root->at(bytesConstRef(&h));
  396. }
  397. void MemTrie::insert(std::string const& _key, std::string const& _value)
  398. {
  399. if (_value.empty())
  400. remove(_key);
  401. auto h = asNibbles(_key);
  402. m_root = m_root ? m_root->insert(&h, _value) : new TrieLeafNode(bytesConstRef(&h), _value);
  403. }
  404. void MemTrie::remove(std::string const& _key)
  405. {
  406. if (m_root)
  407. {
  408. auto h = asNibbles(_key);
  409. m_root = m_root->remove(&h);
  410. }
  411. }
  412. }