github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/light/nodeset.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:39</date> 10 //</624450096456536064> 11 12 13 package light 14 15 import ( 16 "errors" 17 "sync" 18 19 "github.com/ethereum/go-ethereum/common" 20 "github.com/ethereum/go-ethereum/crypto" 21 "github.com/ethereum/go-ethereum/ethdb" 22 "github.com/ethereum/go-ethereum/rlp" 23 ) 24 25 //nodeset存储一组trie节点。它实现了trie.database,还可以 26 //作为另一个trie.database的缓存。 27 type NodeSet struct { 28 nodes map[string][]byte 29 order []string 30 31 dataSize int 32 lock sync.RWMutex 33 } 34 35 //newnodeset创建空节点集 36 func NewNodeSet() *NodeSet { 37 return &NodeSet{ 38 nodes: make(map[string][]byte), 39 } 40 } 41 42 //在集合中放置存储新节点 43 func (db *NodeSet) Put(key []byte, value []byte) error { 44 db.lock.Lock() 45 defer db.lock.Unlock() 46 47 if _, ok := db.nodes[string(key)]; ok { 48 return nil 49 } 50 keystr := string(key) 51 52 db.nodes[keystr] = common.CopyBytes(value) 53 db.order = append(db.order, keystr) 54 db.dataSize += len(value) 55 56 return nil 57 } 58 59 //get返回存储节点 60 func (db *NodeSet) Get(key []byte) ([]byte, error) { 61 db.lock.RLock() 62 defer db.lock.RUnlock() 63 64 if entry, ok := db.nodes[string(key)]; ok { 65 return entry, nil 66 } 67 return nil, errors.New("not found") 68 } 69 70 //如果节点集包含给定的键,则返回true 71 func (db *NodeSet) Has(key []byte) (bool, error) { 72 _, err := db.Get(key) 73 return err == nil, nil 74 } 75 76 //keycount返回集合中的节点数 77 func (db *NodeSet) KeyCount() int { 78 db.lock.RLock() 79 defer db.lock.RUnlock() 80 81 return len(db.nodes) 82 } 83 84 //data size返回集合中节点的聚合数据大小 85 func (db *NodeSet) DataSize() int { 86 db.lock.RLock() 87 defer db.lock.RUnlock() 88 89 return db.dataSize 90 } 91 92 //节点列表将节点集转换为节点列表 93 func (db *NodeSet) NodeList() NodeList { 94 db.lock.RLock() 95 defer db.lock.RUnlock() 96 97 var values NodeList 98 for _, key := range db.order { 99 values = append(values, db.nodes[key]) 100 } 101 return values 102 } 103 104 //存储将集的内容写入给定的数据库 105 func (db *NodeSet) Store(target ethdb.Putter) { 106 db.lock.RLock() 107 defer db.lock.RUnlock() 108 109 for key, value := range db.nodes { 110 target.Put([]byte(key), value) 111 } 112 } 113 114 //nodelist存储trie节点的有序列表。它实现ethdb.putter。 115 type NodeList []rlp.RawValue 116 117 //存储将列表的内容写入给定的数据库 118 func (n NodeList) Store(db ethdb.Putter) { 119 for _, node := range n { 120 db.Put(crypto.Keccak256(node), node) 121 } 122 } 123 124 //节点集将节点列表转换为节点集 125 func (n NodeList) NodeSet() *NodeSet { 126 db := NewNodeSet() 127 n.Store(db) 128 return db 129 } 130 131 //在列表末尾放置一个新节点 132 func (n *NodeList) Put(key []byte, value []byte) error { 133 *n = append(*n, value) 134 return nil 135 } 136 137 //data size返回列表中节点的聚合数据大小 138 func (n NodeList) DataSize() int { 139 var size int 140 for _, node := range n { 141 size += len(node) 142 } 143 return size 144 } 145