github.com/amazechain/amc@v0.1.3/internal/amcdb/lmdb/iterater.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package lmdb 18 19 import ( 20 "github.com/amazechain/amc/common/db" 21 "github.com/erigontech/mdbx-go/mdbx" 22 "runtime" 23 ) 24 25 /* 26 */ 27 type Iterator struct { 28 *mdbx.Cursor 29 txn *mdbx.Txn 30 31 key []byte 32 value []byte 33 err error 34 } 35 36 func newIterator(dbi *DBI, key []byte) (db.IIterator, error) { 37 runtime.LockOSThread() 38 txn, err := dbi.env.BeginTxn(nil, 0) 39 if err != nil { 40 runtime.UnlockOSThread() 41 return nil, err 42 } 43 cur, err := txn.OpenCursor(*dbi.DBI) 44 if err != nil { 45 runtime.UnlockOSThread() 46 return nil, err 47 } 48 49 var ( 50 k, v []byte 51 ) 52 53 if key != nil { 54 k, v, err = cur.Get(key, nil, mdbx.SetKey) 55 } else { 56 k, v, err = cur.Get(nil, nil, mdbx.First) 57 } 58 59 if err != nil { 60 runtime.UnlockOSThread() 61 cur.Close() 62 txn.Abort() 63 return nil, err 64 } 65 66 it := Iterator{ 67 Cursor: cur, 68 txn: txn, 69 key: k, 70 value: v, 71 err: nil, 72 } 73 return &it, nil 74 } 75 76 func (it *Iterator) Next() error { 77 it.key, it.value, it.err = it.Cursor.Get(nil, nil, mdbx.Next) 78 return it.err 79 } 80 81 func (it *Iterator) Key() ([]byte, error) { 82 return it.key, it.err 83 } 84 85 func (it *Iterator) Prev() error { 86 it.key, it.value, it.err = it.Cursor.Get(nil, nil, mdbx.Prev) 87 return it.err 88 } 89 90 func (it *Iterator) Value() ([]byte, error) { 91 return it.value, it.err 92 } 93 func (it *Iterator) Close() { 94 it.Cursor.Close() 95 it.txn.Abort() 96 runtime.UnlockOSThread() 97 }