Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lmdb: internal C.MDB_val fields in Txn for re-use during Get/PutReserve #62

Merged
merged 1 commit into from
Mar 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 25 additions & 23 deletions lmdb/cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,63 +139,62 @@ func (c *Cursor) DBI() DBI {
//
// See mdb_cursor_get.
func (c *Cursor) Get(setkey, setval []byte, op uint) (key, val []byte, err error) {
var k, v *C.MDB_val
switch {
case len(setkey) == 0:
k, v, err = c.getVal0(op)
err = c.getVal0(op)
case len(setval) == 0:
k, v, err = c.getVal1(setkey, op)
err = c.getVal1(setkey, op)
default:
k, v, err = c.getVal2(setkey, setval, op)
err = c.getVal2(setkey, setval, op)
}
if err != nil {
*c.txn.key = C.MDB_val{}
*c.txn.val = C.MDB_val{}
return nil, nil, err
}
return c.txn.bytes(k), c.txn.bytes(v), nil
k := c.txn.bytes(c.txn.key)
v := c.txn.bytes(c.txn.val)
*c.txn.key = C.MDB_val{}
*c.txn.val = C.MDB_val{}
return k, v, nil
}

// getVal0 retrieves items from the database without using given key or value
// data for reference (Next, First, Last, etc).
//
// See mdb_cursor_get.
func (c *Cursor) getVal0(op uint) (key, val *C.MDB_val, err error) {
key = new(C.MDB_val)
val = new(C.MDB_val)
ret := C.mdb_cursor_get(c._c, (*C.MDB_val)(key), (*C.MDB_val)(val), C.MDB_cursor_op(op))
return key, val, operrno("mdb_cursor_get", ret)
func (c *Cursor) getVal0(op uint) error {
ret := C.mdb_cursor_get(c._c, c.txn.key, c.txn.val, C.MDB_cursor_op(op))
return operrno("mdb_cursor_get", ret)
}

// getVal1 retrieves items from the database using key data for reference
// (Set, SetRange, etc).
//
// See mdb_cursor_get.
func (c *Cursor) getVal1(setkey []byte, op uint) (key, val *C.MDB_val, err error) {
key = new(C.MDB_val)
val = new(C.MDB_val)
func (c *Cursor) getVal1(setkey []byte, op uint) error {
ret := C.lmdbgo_mdb_cursor_get1(
c._c,
unsafe.Pointer(&setkey[0]), C.size_t(len(setkey)),
(*C.MDB_val)(key), (*C.MDB_val)(val),
c.txn.key, c.txn.val,
C.MDB_cursor_op(op),
)
return key, val, operrno("mdb_cursor_get", ret)
return operrno("mdb_cursor_get", ret)
}

// getVal2 retrieves items from the database using key and value data for
// reference (GetBoth, GetBothRange, etc).
//
// See mdb_cursor_get.
func (c *Cursor) getVal2(setkey, setval []byte, op uint) (key, val *C.MDB_val, err error) {
key = new(C.MDB_val)
val = new(C.MDB_val)
func (c *Cursor) getVal2(setkey, setval []byte, op uint) error {
ret := C.lmdbgo_mdb_cursor_get2(
c._c,
unsafe.Pointer(&setkey[0]), C.size_t(len(setkey)),
unsafe.Pointer(&setval[0]), C.size_t(len(setval)),
(*C.MDB_val)(key), (*C.MDB_val)(val),
c.txn.key, c.txn.val,
C.MDB_cursor_op(op),
)
return key, val, operrno("mdb_cursor_get", ret)
return operrno("mdb_cursor_get", ret)
}

func (c *Cursor) putNilKey(flags uint) error {
Expand Down Expand Up @@ -231,18 +230,21 @@ func (c *Cursor) PutReserve(key []byte, n int, flags uint) ([]byte, error) {
return nil, c.putNilKey(flags)
}

val := &C.MDB_val{mv_size: C.size_t(n)}
c.txn.val.mv_size = C.size_t(n)
ret := C.lmdbgo_mdb_cursor_put1(
c._c,
unsafe.Pointer(&key[0]), C.size_t(len(key)),
(*C.MDB_val)(val),
c.txn.val,
C.uint(flags|C.MDB_RESERVE),
)
err := operrno("mdb_cursor_put", ret)
if err != nil {
*c.txn.val = C.MDB_val{}
return nil, err
}
return getBytes(val), nil
b := getBytes(c.txn.val)
*c.txn.val = C.MDB_val{}
return b, nil
}

// PutMulti stores a set of contiguous items with stride size under key.
Expand Down
24 changes: 18 additions & 6 deletions lmdb/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type Txn struct {
env *Env
_txn *C.MDB_txn
errLogf func(format string, v ...interface{})
key *C.MDB_val
val *C.MDB_val
}

// beginTxn does not lock the OS thread which is a prerequisite for creating a
Expand All @@ -58,11 +60,16 @@ func beginTxn(env *Env, parent *Txn, flags uint) (*Txn, error) {
readonly: (flags&Readonly != 0),
env: env,
}

var ptxn *C.MDB_txn
if parent == nil {
ptxn = nil
txn.key = new(C.MDB_val)
txn.val = new(C.MDB_val)
} else {
ptxn = parent._txn
txn.key = parent.key
txn.val = parent.val
}
ret := C.mdb_txn_begin(env._env, ptxn, C.uint(flags), &txn._txn)
if ret != success {
Expand Down Expand Up @@ -275,17 +282,19 @@ func (txn *Txn) bytes(val *C.MDB_val) []byte {
// See mdb_get.
func (txn *Txn) Get(dbi DBI, key []byte) ([]byte, error) {
kdata, kn := valBytes(key)
val := new(C.MDB_val)
ret := C.lmdbgo_mdb_get(
txn._txn, C.MDB_dbi(dbi),
unsafe.Pointer(&kdata[0]), C.size_t(kn),
(*C.MDB_val)(val),
txn.val,
)
err := operrno("mdb_get", ret)
if err != nil {
*txn.val = C.MDB_val{}
return nil, err
}
return txn.bytes(val), nil
b := txn.bytes(txn.val)
*txn.val = C.MDB_val{}
return b, nil
}

func (txn *Txn) putNilKey(dbi DBI, flags uint) error {
Expand Down Expand Up @@ -323,18 +332,21 @@ func (txn *Txn) PutReserve(dbi DBI, key []byte, n int, flags uint) ([]byte, erro
if len(key) == 0 {
return nil, txn.putNilKey(dbi, flags)
}
val := &C.MDB_val{mv_size: C.size_t(n)}
txn.val.mv_size = C.size_t(n)
ret := C.lmdbgo_mdb_put1(
txn._txn, C.MDB_dbi(dbi),
unsafe.Pointer(&key[0]), C.size_t(len(key)),
(*C.MDB_val)(val),
txn.val,
C.uint(flags|C.MDB_RESERVE),
)
err := operrno("mdb_put", ret)
if err != nil {
*txn.val = C.MDB_val{}
return nil, err
}
return getBytes(val), nil
b := getBytes(txn.val)
*txn.val = C.MDB_val{}
return b, nil
}

// Del deletes an item from database dbi. Del ignores val unless dbi has the
Expand Down