lmdb.go (1788B)
1 package lmdb 2 3 import ( 4 "log" 5 6 "github.com/ledgerwatch/lmdb-go/lmdb" 7 8 "defalsify.org/go-eth-proxy/store" 9 ) 10 11 type LmdbStore struct { 12 store store.Store 13 env *lmdb.Env 14 dbi lmdb.DBI 15 } 16 17 /// TODO: not create 18 func NewStore(path string) (*LmdbStore, error) { 19 var err error 20 21 log.Printf("lmdb store path: %s", path) 22 o := &LmdbStore{} 23 o.env, err = lmdb.NewEnv() 24 if err != nil { 25 return nil, err 26 } 27 err = o.env.SetMaxDBs(1) 28 if err != nil { 29 return nil, err 30 } 31 err = o.env.SetMapSize(1 << 30) 32 if err != nil { 33 return nil, err 34 } 35 err = o.env.Open(path, 0, 0644) 36 if err != nil { 37 return nil, err 38 } 39 err = o.env.Update(func(txn *lmdb.Txn) (error) { 40 var err error 41 o.dbi, err = txn.OpenRoot(0) 42 return err 43 }) 44 if err != nil { 45 return nil, err 46 } 47 return o, nil 48 } 49 50 func (l *LmdbStore) get(pfx string, k []byte) ([]byte, error) { 51 var b []byte 52 53 n := len(pfx) 54 kp := make([]byte, len(k) + n) 55 copy(kp, []byte(pfx)) 56 copy(kp[n:], k) 57 58 err := l.env.View(func(txn *lmdb.Txn) (error) { 59 log.Printf("get %x %v", kp, txn) 60 v, err := txn.Get(l.dbi, kp) 61 if err != nil { 62 return err 63 } 64 b = make([]byte, len(v)) 65 copy(b, v) 66 return nil 67 }) 68 log.Printf("lmdb result: %s", b) 69 if err != nil { 70 return nil, err 71 } 72 return b, nil 73 } 74 75 76 func (l *LmdbStore) GetTransaction(k []byte) ([]byte, error) { 77 return l.get("tx/src/", k) 78 } 79 80 func (l *LmdbStore) GetBlockNumber(n []byte) ([]byte, error) { 81 b := make([]byte, 8) 82 copy(b[8-len(n):], n) 83 k, err := l.get("block/num/", b) 84 if err != nil { 85 return nil, err 86 } 87 return l.get("block/src/", k) 88 } 89 90 func (l *LmdbStore) GetBlock(k []byte) ([]byte, error) { 91 return l.get("block/src/", k) 92 } 93 94 func (l *LmdbStore) GetTransactionReceipt(k []byte) ([]byte, error) { 95 return l.get("rcpt/src/", k) 96 } 97 98 func (l *LmdbStore) Close() { 99 l.env.Close() 100 }