github.com/insight-chain/inb-go@v1.1.3-0.20191221022159-da049980ae38/swarm/shed/db.go (about) 1 // Copyright 2018 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 17 // Package shed provides a simple abstraction components to compose 18 // more complex operations on storage data organized in fields and indexes. 19 // 20 // Only type which holds logical information about swarm storage chunks data 21 // and metadata is IndexItem. This part is not generalized mostly for 22 // performance reasons. 23 package shed 24 25 import ( 26 "github.com/insight-chain/inb-go/metrics" 27 "github.com/syndtr/goleveldb/leveldb" 28 "github.com/syndtr/goleveldb/leveldb/iterator" 29 "github.com/syndtr/goleveldb/leveldb/opt" 30 ) 31 32 // The limit for LevelDB OpenFilesCacheCapacity. 33 const openFileLimit = 128 34 35 // DB provides abstractions over LevelDB in order to 36 // implement complex structures using fields and ordered indexes. 37 // It provides a schema functionality to store fields and indexes 38 // information about naming and types. 39 type DB struct { 40 ldb *leveldb.DB 41 } 42 43 // NewDB constructs a new DB and validates the schema 44 // if it exists in database on the given path. 45 func NewDB(path string) (db *DB, err error) { 46 ldb, err := leveldb.OpenFile(path, &opt.Options{ 47 OpenFilesCacheCapacity: openFileLimit, 48 }) 49 if err != nil { 50 return nil, err 51 } 52 db = &DB{ 53 ldb: ldb, 54 } 55 56 if _, err = db.getSchema(); err != nil { 57 if err == leveldb.ErrNotFound { 58 // save schema with initialized default fields 59 if err = db.putSchema(schema{ 60 Fields: make(map[string]fieldSpec), 61 Indexes: make(map[byte]indexSpec), 62 }); err != nil { 63 return nil, err 64 } 65 } else { 66 return nil, err 67 } 68 } 69 return db, nil 70 } 71 72 // Put wraps LevelDB Put method to increment metrics counter. 73 func (db *DB) Put(key []byte, value []byte) (err error) { 74 err = db.ldb.Put(key, value, nil) 75 if err != nil { 76 metrics.GetOrRegisterCounter("DB.putFail", nil).Inc(1) 77 return err 78 } 79 metrics.GetOrRegisterCounter("DB.put", nil).Inc(1) 80 return nil 81 } 82 83 // Get wraps LevelDB Get method to increment metrics counter. 84 func (db *DB) Get(key []byte) (value []byte, err error) { 85 value, err = db.ldb.Get(key, nil) 86 if err != nil { 87 if err == leveldb.ErrNotFound { 88 metrics.GetOrRegisterCounter("DB.getNotFound", nil).Inc(1) 89 } else { 90 metrics.GetOrRegisterCounter("DB.getFail", nil).Inc(1) 91 } 92 return nil, err 93 } 94 metrics.GetOrRegisterCounter("DB.get", nil).Inc(1) 95 return value, nil 96 } 97 98 // Delete wraps LevelDB Delete method to increment metrics counter. 99 func (db *DB) Delete(key []byte) (err error) { 100 err = db.ldb.Delete(key, nil) 101 if err != nil { 102 metrics.GetOrRegisterCounter("DB.deleteFail", nil).Inc(1) 103 return err 104 } 105 metrics.GetOrRegisterCounter("DB.delete", nil).Inc(1) 106 return nil 107 } 108 109 // NewIterator wraps LevelDB NewIterator method to increment metrics counter. 110 func (db *DB) NewIterator() iterator.Iterator { 111 metrics.GetOrRegisterCounter("DB.newiterator", nil).Inc(1) 112 113 return db.ldb.NewIterator(nil, nil) 114 } 115 116 // WriteBatch wraps LevelDB Write method to increment metrics counter. 117 func (db *DB) WriteBatch(batch *leveldb.Batch) (err error) { 118 err = db.ldb.Write(batch, nil) 119 if err != nil { 120 metrics.GetOrRegisterCounter("DB.writebatchFail", nil).Inc(1) 121 return err 122 } 123 metrics.GetOrRegisterCounter("DB.writebatch", nil).Inc(1) 124 return nil 125 } 126 127 // Close closes LevelDB database. 128 func (db *DB) Close() (err error) { 129 return db.ldb.Close() 130 }