nodeset.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. // Get returns a stored node
  53. func (db *NodeSet) Get(key []byte) ([]byte, error) {
  54. db.lock.RLock()
  55. defer db.lock.RUnlock()
  56. if entry, ok := db.nodes[string(key)]; ok {
  57. return entry, nil
  58. }
  59. return nil, errors.New("not found")
  60. }
  61. // Has returns true if the node set contains the given key
  62. func (db *NodeSet) Has(key []byte) (bool, error) {
  63. _, err := db.Get(key)
  64. return err == nil, nil
  65. }
  66. // KeyCount returns the number of nodes in the set
  67. func (db *NodeSet) KeyCount() int {
  68. db.lock.RLock()
  69. defer db.lock.RUnlock()
  70. return len(db.nodes)
  71. }
  72. // DataSize returns the aggregated data size of nodes in the set
  73. func (db *NodeSet) DataSize() int {
  74. db.lock.RLock()
  75. defer db.lock.RUnlock()
  76. return db.dataSize
  77. }
  78. // NodeList converts the node set to a NodeList
  79. func (db *NodeSet) NodeList() NodeList {
  80. db.lock.RLock()
  81. defer db.lock.RUnlock()
  82. var values NodeList
  83. for _, key := range db.order {
  84. values = append(values, db.nodes[key])
  85. }
  86. return values
  87. }
  88. // Store writes the contents of the set to the given database
  89. func (db *NodeSet) Store(target ethdb.Putter) {
  90. db.lock.RLock()
  91. defer db.lock.RUnlock()
  92. for key, value := range db.nodes {
  93. target.Put([]byte(key), value)
  94. }
  95. }
  96. // NodeList stores an ordered list of trie nodes. It implements ethdb.Putter.
  97. type NodeList []rlp.RawValue
  98. // Store writes the contents of the list to the given database
  99. func (n NodeList) Store(db ethdb.Putter) {
  100. for _, node := range n {
  101. db.Put(crypto.Keccak256(node), node)
  102. }
  103. }
  104. // NodeSet converts the node list to a NodeSet
  105. func (n NodeList) NodeSet() *NodeSet {
  106. db := NewNodeSet()
  107. n.Store(db)
  108. return db
  109. }
  110. // Put stores a new node at the end of the list
  111. func (n *NodeList) Put(key []byte, value []byte) error {
  112. *n = append(*n, value)
  113. return nil
  114. }
  115. // DataSize returns the aggregated data size of nodes in the list
  116. func (n NodeList) DataSize() int {
  117. var size int
  118. for _, node := range n {
  119. size += len(node)
  120. }
  121. return size
  122. }