nodeset.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright 2014 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. db map[string][]byte
  29. dataSize int
  30. lock sync.RWMutex
  31. }
  32. // NewNodeSet creates an empty node set
  33. func NewNodeSet() *NodeSet {
  34. return &NodeSet{
  35. db: make(map[string][]byte),
  36. }
  37. }
  38. // Put stores a new node in the set
  39. func (db *NodeSet) Put(key []byte, value []byte) error {
  40. db.lock.Lock()
  41. defer db.lock.Unlock()
  42. if _, ok := db.db[string(key)]; !ok {
  43. db.db[string(key)] = common.CopyBytes(value)
  44. db.dataSize += len(value)
  45. }
  46. return nil
  47. }
  48. // Get returns a stored node
  49. func (db *NodeSet) Get(key []byte) ([]byte, error) {
  50. db.lock.RLock()
  51. defer db.lock.RUnlock()
  52. if entry, ok := db.db[string(key)]; ok {
  53. return entry, nil
  54. }
  55. return nil, errors.New("not found")
  56. }
  57. // Has returns true if the node set contains the given key
  58. func (db *NodeSet) Has(key []byte) (bool, error) {
  59. _, err := db.Get(key)
  60. return err == nil, nil
  61. }
  62. // KeyCount returns the number of nodes in the set
  63. func (db *NodeSet) KeyCount() int {
  64. db.lock.RLock()
  65. defer db.lock.RUnlock()
  66. return len(db.db)
  67. }
  68. // DataSize returns the aggregated data size of nodes in the set
  69. func (db *NodeSet) DataSize() int {
  70. db.lock.RLock()
  71. defer db.lock.RUnlock()
  72. return db.dataSize
  73. }
  74. // NodeList converts the node set to a NodeList
  75. func (db *NodeSet) NodeList() NodeList {
  76. db.lock.RLock()
  77. defer db.lock.RUnlock()
  78. var values NodeList
  79. for _, value := range db.db {
  80. values = append(values, value)
  81. }
  82. return values
  83. }
  84. // Store writes the contents of the set to the given database
  85. func (db *NodeSet) Store(target ethdb.Putter) {
  86. db.lock.RLock()
  87. defer db.lock.RUnlock()
  88. for key, value := range db.db {
  89. target.Put([]byte(key), value)
  90. }
  91. }
  92. // NodeList stores an ordered list of trie nodes. It implements ethdb.Putter.
  93. type NodeList []rlp.RawValue
  94. // Store writes the contents of the list to the given database
  95. func (n NodeList) Store(db ethdb.Putter) {
  96. for _, node := range n {
  97. db.Put(crypto.Keccak256(node), node)
  98. }
  99. }
  100. // NodeSet converts the node list to a NodeSet
  101. func (n NodeList) NodeSet() *NodeSet {
  102. db := NewNodeSet()
  103. n.Store(db)
  104. return db
  105. }
  106. // Put stores a new node at the end of the list
  107. func (n *NodeList) Put(key []byte, value []byte) error {
  108. *n = append(*n, value)
  109. return nil
  110. }
  111. // DataSize returns the aggregated data size of nodes in the list
  112. func (n NodeList) DataSize() int {
  113. var size int
  114. for _, node := range n {
  115. size += len(node)
  116. }
  117. return size
  118. }