github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/fs/blockchain/trie/trie.h (about)

     1  // Copyright (C) 2018 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or
     6  // modify
     7  // it under the terms of the GNU General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or
     9  // (at your option) any later version.
    10  //
    11  // the go-nebulas library is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU General Public License
    17  // along with the go-nebulas library.  If not, see
    18  // <http://www.gnu.org/licenses/>.
    19  //
    20  
    21  #pragma once
    22  #include "common/byte.h"
    23  #include "common/common.h"
    24  #include "crypto/hash.h"
    25  #include "fs/blockchain/trie/byte_shared.h"
    26  #include "fs/proto/trie.pb.h"
    27  #include "fs/rocksdb_storage.h"
    28  
    29  namespace neb {
    30  namespace fs {
    31  
    32  typedef int32_t trie_node_type;
    33  constexpr static int32_t trie_node_unknown = 0;
    34  constexpr static int32_t trie_node_extension = 1;
    35  constexpr static int32_t trie_node_leaf = 2;
    36  constexpr static int32_t trie_node_branch = 3;
    37  
    38  class trie_node {
    39  public:
    40    trie_node(trie_node_type type);
    41    trie_node(const neb::bytes &triepb_bytes);
    42  
    43    trie_node(const std::vector<neb::bytes> &val);
    44  
    45    trie_node_type get_trie_node_type();
    46  
    47    inline const neb::bytes &val_at(size_t index) const { return m_val[index]; }
    48    inline neb::bytes &val_at(size_t index) { return m_val[index]; }
    49  
    50    void change_to_type(trie_node_type new_type);
    51  
    52    inline const hash_t &hash() const { return m_hash; }
    53  
    54    inline hash_t &hash() { return m_hash; }
    55  
    56    std::unique_ptr<triepb::Node> to_proto() const;
    57  
    58  private:
    59    std::vector<neb::bytes> m_val;
    60    hash_t m_hash;
    61  };
    62  
    63  typedef std::unique_ptr<trie_node> trie_node_ptr;
    64  
    65  class trie {
    66  public:
    67    trie(const hash_t &hash);
    68    trie();
    69  
    70    bool get_trie_node(const neb::bytes &root_hash, const neb::bytes &key,
    71                       neb::bytes &trie_node);
    72  
    73    hash_t put(const hash_t &key, const neb::bytes &val);
    74  
    75    trie_node_ptr create_node(const std::vector<neb::bytes> &val);
    76  
    77    void commit_node(trie_node *node);
    78  
    79    inline const hash_t &root_hash() const { return m_root_hash; }
    80    inline hash_t &root_hash() { return m_root_hash; }
    81    inline bool empty() const { return m_root_hash.size() == 0; }
    82  
    83  private:
    84    std::unique_ptr<trie_node> fetch_node(const neb::bytes &hash);
    85    std::unique_ptr<trie_node> fetch_node(const hash_t &hash);
    86  
    87    hash_t update(const hash_t &root, const neb::bytes &route,
    88                  const neb::bytes &val);
    89  
    90    hash_t update_when_meet_branch(trie_node *root_node, const neb::bytes &route,
    91                                   const neb::bytes &val);
    92    hash_t update_when_meet_ext(trie_node *root_node, const neb::bytes &route,
    93                                const neb::bytes &val);
    94    hash_t update_when_meet_leaf(trie_node *root_node, const neb::bytes &route,
    95                                 const neb::bytes &val);
    96  
    97  public:
    98    static neb::bytes route_to_key(const neb::bytes &route);
    99    template <typename T> static neb::bytes key_to_route(const T &key) {
   100  
   101      size_t size = key.size() << 1;
   102      neb::bytes value(size);
   103  
   104      if (size > 0) {
   105        for (size_t i = 0; i < key.size(); i++) {
   106          byte_shared byte(key[i]);
   107          value[i << 1] = byte.bits_high();
   108          value[(i << 1) + 1] = byte.bits_low();
   109        }
   110      }
   111      return value;
   112    }
   113    template <typename T1, typename T2>
   114    static size_t prefix_len(const T1 &s, const T2 &t) {
   115      auto s_len = s.size();
   116      auto t_len = t.size();
   117      size_t min_len = std::min(s_len, t_len);
   118      for (size_t i = 0; i < min_len; i++) {
   119        if (s[i] != t[i]) {
   120          return i;
   121        }
   122      }
   123      return min_len;
   124    }
   125    template <typename T1>
   126    static size_t prefix_len(const T1 &s, const byte_t *t, size_t t_len) {
   127      auto s_len = s.size();
   128      size_t min_len = std::min(s_len, t_len);
   129      for (size_t i = 0; i < min_len; i++) {
   130        if (s[i] != t[i]) {
   131          return i;
   132        }
   133      }
   134      return min_len;
   135    }
   136  
   137  private:
   138    hash_t m_root_hash;
   139  };
   140  } // namespace fs
   141  } // namespace neb