|
| 1 | +// Copyright 2025 the libevm authors. |
| 2 | +// |
| 3 | +// The libevm additions to go-ethereum are free software: you can redistribute |
| 4 | +// them and/or modify them under the terms of the GNU Lesser General Public License |
| 5 | +// as published by the Free Software Foundation, either version 3 of the License, |
| 6 | +// or (at your option) any later version. |
| 7 | +// |
| 8 | +// The libevm additions are distributed in the hope that they will be useful, |
| 9 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
| 11 | +// General Public License for more details. |
| 12 | +// |
| 13 | +// You should have received a copy of the GNU Lesser General Public License |
| 14 | +// along with the go-ethereum library. If not, see |
| 15 | +// <http://www.gnu.org/licenses/>. |
| 16 | + |
| 17 | +package rawdb |
| 18 | + |
| 19 | +import ( |
| 20 | + "github.com/ava-labs/libevm/common" |
| 21 | + "github.com/ava-labs/libevm/libevm/options" |
| 22 | +) |
| 23 | + |
| 24 | +// An InspectDatabaseOption configures the behaviour of [InspectDatabase]. For |
| 25 | +// each type of option, only one instance can be used in the same call to |
| 26 | +// InspectDatabase(). |
| 27 | +type InspectDatabaseOption = options.Option[inspectDatabaseConfig] |
| 28 | + |
| 29 | +type inspectDatabaseConfig struct { |
| 30 | + statRecorder func([]byte, common.StorageSize) bool |
| 31 | + isMeta func([]byte) bool |
| 32 | + statsTransformer func([][]string) [][]string |
| 33 | +} |
| 34 | + |
| 35 | +func (c inspectDatabaseConfig) recordStat(key []byte, size common.StorageSize) bool { |
| 36 | + if r := c.statRecorder; r != nil { |
| 37 | + return r(key, size) |
| 38 | + } |
| 39 | + return false |
| 40 | +} |
| 41 | + |
| 42 | +func (c inspectDatabaseConfig) isMetadata(key []byte) bool { |
| 43 | + if m := c.isMeta; m != nil { |
| 44 | + return m(key) |
| 45 | + } |
| 46 | + return false |
| 47 | +} |
| 48 | + |
| 49 | +func (c inspectDatabaseConfig) transformStats(stats [][]string) [][]string { |
| 50 | + if f := c.statsTransformer; f != nil { |
| 51 | + return f(stats) |
| 52 | + } |
| 53 | + return stats |
| 54 | +} |
| 55 | + |
| 56 | +func newInspectOpt(fn func(*inspectDatabaseConfig)) InspectDatabaseOption { |
| 57 | + return options.Func[inspectDatabaseConfig](fn) |
| 58 | +} |
| 59 | + |
| 60 | +// WithDatabaseStatRecorder returns an option that results in `rec` being called |
| 61 | +// for every `key` not otherwise matched by the [InspectDatabase] iterator loop. |
| 62 | +// The returned boolean signals whether the recorder matches the key, thus |
| 63 | +// stopping further matches. |
| 64 | +func WithDatabaseStatRecorder(rec func(key []byte, _ common.StorageSize) bool) InspectDatabaseOption { |
| 65 | + return newInspectOpt(func(c *inspectDatabaseConfig) { |
| 66 | + c.statRecorder = rec |
| 67 | + }) |
| 68 | +} |
| 69 | + |
| 70 | +// A DatabaseStat stores total size and counts for a parameter measured by |
| 71 | +// [InspectDatabase]. It is exported for use with [WithDatabaseStatRecorder]. |
| 72 | +type DatabaseStat = stat |
| 73 | + |
| 74 | +// WithDatabaseMetadataKeys returns an option that results in the `key` size |
| 75 | +// being counted with the metadata statistic i.f.f. the function returns true. |
| 76 | +func WithDatabaseMetadataKeys(isMetadata func(key []byte) bool) InspectDatabaseOption { |
| 77 | + return newInspectOpt(func(c *inspectDatabaseConfig) { |
| 78 | + c.isMeta = isMetadata |
| 79 | + }) |
| 80 | +} |
| 81 | + |
| 82 | +// WithDatabaseStatsTransformer returns an option that causes all statistics to |
| 83 | +// be passed to the provided function, with its return value being printed |
| 84 | +// instead of the original values. |
| 85 | +func WithDatabaseStatsTransformer(transform func([][]string) [][]string) InspectDatabaseOption { |
| 86 | + return newInspectOpt(func(c *inspectDatabaseConfig) { |
| 87 | + c.statsTransformer = transform |
| 88 | + }) |
| 89 | +} |
0 commit comments