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