github.com/klaytn/klaytn@v1.12.1/storage/database/interface.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from ethdb/interface.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package database 22 23 import "strings" 24 25 // Code using batches should try to add this much data to the batch. 26 // The value was determined empirically. 27 28 type DBType string 29 30 const ( 31 LevelDB DBType = "LevelDB" 32 RocksDB = "RocksDB" 33 BadgerDB = "BadgerDB" 34 MemoryDB = "MemoryDB" 35 DynamoDB = "DynamoDBS3" 36 ShardedDB = "ShardedDB" 37 ) 38 39 // ToValid converts DBType to a valid one. 40 // If it is unable to convert, "" is returned. 41 func (db DBType) ToValid() DBType { 42 validDBType := []DBType{LevelDB, RocksDB, BadgerDB, MemoryDB, DynamoDB} 43 44 for _, vdb := range validDBType { 45 if strings.ToLower(string(vdb)) == strings.ToLower(string(db)) { 46 return vdb 47 } 48 } 49 50 return "" 51 } 52 53 // selfShardable returns if the db is able to shard by itself or not 54 func (db DBType) selfShardable() bool { 55 switch db { 56 case DynamoDB: 57 return true 58 } 59 return false 60 } 61 62 // KeyValueWriter wraps the Put method of a backing data store. 63 type KeyValueWriter interface { 64 // Put inserts the given value into the key-value data store. 65 Put(key []byte, value []byte) error 66 67 // Delete removes the key from the key-value data store. 68 Delete(key []byte) error 69 } 70 71 // KeyValueStater wraps the Stat method of a backing data store. 72 type KeyValueStater interface { 73 // Stat returns a particular internal stat of the database. 74 Stat(property string) (string, error) 75 } 76 77 // Compacter wraps the Compact method of a backing data store. 78 type Compacter interface { 79 // Compact flattens the underlying data store for the given key range. In essence, 80 // deleted and overwritten versions are discarded, and the data is rearranged to 81 // reduce the cost of operations needed to access them. 82 // 83 // A nil start is treated as a key before all keys in the data store; a nil limit 84 // is treated as a key after all keys in the data store. If both is nil then it 85 // will compact entire data store. 86 Compact(start []byte, limit []byte) error 87 } 88 89 // Database wraps all database operations. All methods are safe for concurrent use. 90 type Database interface { 91 KeyValueWriter 92 KeyValueStater 93 Compacter 94 95 Get(key []byte) ([]byte, error) 96 Has(key []byte) (bool, error) 97 Close() 98 NewBatch() Batch 99 Type() DBType 100 Meter(prefix string) 101 Iteratee 102 103 TryCatchUpWithPrimary() error 104 } 105 106 func WriteBatches(batches ...Batch) (int, error) { 107 bytes := 0 108 for _, batch := range batches { 109 if batch.ValueSize() > 0 { 110 bytes += batch.ValueSize() 111 if err := batch.Write(); err != nil { 112 return 0, err 113 } 114 batch.Reset() 115 } 116 } 117 return bytes, nil 118 } 119 120 func WriteBatchesParallel(batches ...Batch) (int, error) { 121 type result struct { 122 bytes int 123 err error 124 } 125 126 resultCh := make(chan result, len(batches)) 127 for _, batch := range batches { 128 go func(batch Batch) { 129 bytes := batch.ValueSize() 130 err := batch.Write() 131 if err != nil { 132 batch.Reset() 133 } 134 resultCh <- result{bytes, err} 135 }(batch) 136 } 137 138 var bytes int 139 for range batches { 140 rst := <-resultCh 141 if rst.err != nil { 142 return bytes, rst.err 143 } 144 bytes += rst.bytes 145 } 146 147 return bytes, nil 148 } 149 150 func WriteBatchesOverThreshold(batches ...Batch) (int, error) { 151 bytes := 0 152 for _, batch := range batches { 153 if batch.ValueSize() >= IdealBatchSize { 154 if err := batch.Write(); err != nil { 155 return 0, err 156 } 157 bytes += batch.ValueSize() 158 batch.Reset() 159 } 160 } 161 return bytes, nil 162 }