nodeset.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package light
  17. import (
  18. "errors"
  19. "sync"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/crypto"
  22. "github.com/ethereum/go-ethereum/ethdb"
  23. "github.com/ethereum/go-ethereum/rlp"
  24. )
  25. // NodeSet stores a set of trie nodes. It implements trie.Database and can also
  26. // act as a cache for another trie.Database.
  27. type NodeSet struct {
  28. nodes map[string][]byte
  29. order []string
  30. dataSize int
  31. lock sync.RWMutex
  32. }
  33. // NewNodeSet creates an empty node set
  34. func NewNodeSet() *NodeSet {
  35. return &NodeSet{
  36. nodes: make(map[string][]byte),
  37. }
  38. }
  39. // Put stores a new node in the set
  40. func (db *NodeSet) Put(key []byte, value []byte) error {
  41. db.lock.Lock()
  42. defer db.lock.Unlock()
  43. if _, ok := db.nodes[string(key)]; ok {
  44. return nil
  45. }
  46. keystr := string(key)
  47. db.nodes[keystr] = common.CopyBytes(value)
  48. db.order = append(db.order, keystr)
  49. db.dataSize += len(value)
  50. return nil
  51. }
  52. // Delete removes a node from the set
  53. func (db *NodeSet) Delete(key []byte) error {
  54. db.lock.Lock()
  55. defer db.lock.Unlock()
  56. delete(db.nodes, string(key))
  57. return nil
  58. }
  59. // Get returns a stored node
  60. func (db *NodeSet) Get(key []byte) ([]byte, error) {
  61. db.lock.RLock()
  62. defer db.lock.RUnlock()
  63. if entry, ok := db.nodes[string(key)]; ok {
  64. return entry, nil
  65. }
  66. return nil, errors.New("not found")
  67. }
  68. // Has returns true if the node set contains the given key
  69. func (db *NodeSet) Has(key []byte) (bool, error) {
  70. _, err := db.Get(key)
  71. return err == nil, nil
  72. }
  73. // KeyCount returns the number of nodes in the set
  74. func (db *NodeSet) KeyCount() int {
  75. db.lock.RLock()
  76. defer db.lock.RUnlock()
  77. return len(db.nodes)
  78. }
  79. // DataSize returns the aggregated data size of nodes in the set
  80. func (db *NodeSet) DataSize() int {
  81. db.lock.RLock()
  82. defer db.lock.RUnlock()
  83. return db.dataSize
  84. }
  85. // NodeList converts the node set to a NodeList
  86. func (db *NodeSet) NodeList() NodeList {
  87. db.lock.RLock()
  88. defer db.lock.RUnlock()
  89. var values NodeList
  90. for _, key := range db.order {
  91. values = append(values, db.nodes[key])
  92. }
  93. return values
  94. }
  95. // Store writes the contents of the set to the given database
  96. func (db *NodeSet) Store(target ethdb.KeyValueWriter) {
  97. db.lock.RLock()
  98. defer db.lock.RUnlock()
  99. for key, value := range db.nodes {
  100. target.Put([]byte(key), value)
  101. }
  102. }
  103. // NodeList stores an ordered list of trie nodes. It implements ethdb.KeyValueWriter.
  104. type NodeList []rlp.RawValue
  105. // Store writes the contents of the list to the given database
  106. func (n NodeList) Store(db ethdb.KeyValueWriter) {
  107. for _, node := range n {
  108. db.Put(crypto.Keccak256(node), node)
  109. }
  110. }
  111. // NodeSet converts the node list to a NodeSet
  112. func (n NodeList) NodeSet() *NodeSet {
  113. db := NewNodeSet()
  114. n.Store(db)
  115. return db
  116. }
  117. // Put stores a new node at the end of the list
  118. func (n *NodeList) Put(key []byte, value []byte) error {
  119. *n = append(*n, value)
  120. return nil
  121. }
  122. // Delete panics as there's no reason to remove a node from the list.
  123. func (n *NodeList) Delete(key []byte) error {
  124. panic("not supported")
  125. }
  126. // DataSize returns the aggregated data size of nodes in the list
  127. func (n NodeList) DataSize() int {
  128. var size int
  129. for _, node := range n {
  130. size += len(node)
  131. }
  132. return size
  133. }