Skip to content

Commit

Permalink
Merge branch 'v0_27'
Browse files Browse the repository at this point in the history
  • Loading branch information
AskAlexSharov committed Feb 22, 2023
2 parents c106280 + 7fc8ae7 commit 7716cdb
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 128 deletions.
65 changes: 36 additions & 29 deletions mdbx/cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ func (c *Cursor) Get(setkey, setval []byte, op uint) (key, val []byte, err error
key = setkey
} else {
if op != LastDup {
key = c.txn.bytes(c.txn.key)
key = castToBytes(c.txn.key)
}
}
val = c.txn.bytes(c.txn.val)
val = castToBytes(c.txn.val)

// Clear transaction storage record storage area for future use and to
// prevent dangling references.
Expand All @@ -184,9 +184,13 @@ func (c *Cursor) getVal0(op uint) error {
//
// See mdb_cursor_get.
func (c *Cursor) getVal1(setkey []byte, op uint) error {
var k *C.char
if len(setkey) > 0 {
k = (*C.char)(unsafe.Pointer(&setkey[0]))
}
ret := C.mdbxgo_cursor_get1(
c._c,
(*C.char)(unsafe.Pointer(&setkey[0])), C.size_t(len(setkey)),
k, C.size_t(len(setkey)),
c.txn.key,
c.txn.val,
C.MDBX_cursor_op(op),
Expand All @@ -199,36 +203,38 @@ func (c *Cursor) getVal1(setkey []byte, op uint) error {
//
// See mdb_cursor_get.
func (c *Cursor) getVal2(setkey, setval []byte, op uint) error {
var k, v *C.char
if len(setkey) > 0 {
k = (*C.char)(unsafe.Pointer(&setkey[0]))
}
if len(setval) > 0 {
v = (*C.char)(unsafe.Pointer(&setval[0]))
}
ret := C.mdbxgo_cursor_get2(
c._c,
(*C.char)(unsafe.Pointer(&setkey[0])), C.size_t(len(setkey)),
(*C.char)(unsafe.Pointer(&setval[0])), C.size_t(len(setval)),
k, C.size_t(len(setkey)),
v, C.size_t(len(setval)),
c.txn.key, c.txn.val,
C.MDBX_cursor_op(op),
)
return operrno("mdbx_cursor_get", ret)
}

func (c *Cursor) putNilKey(flags uint) error {
ret := C.mdbxgo_cursor_put2(c._c, nil, 0, nil, 0, C.MDBX_put_flags_t(flags))
return operrno("mdbx_cursor_put", ret)
}

// Put stores an item in the database.
//
// See mdb_cursor_put.
func (c *Cursor) Put(key, val []byte, flags uint) error {
if len(key) == 0 {
return c.putNilKey(flags)
var k, v *C.char
if len(key) > 0 {
k = (*C.char)(unsafe.Pointer(&key[0]))
}
vn := len(val)
if vn == 0 {
val = []byte{0}
if len(val) > 0 {
v = (*C.char)(unsafe.Pointer(&val[0]))
}
ret := C.mdbxgo_cursor_put2(
c._c,
(*C.char)(unsafe.Pointer(&key[0])), C.size_t(len(key)),
(*C.char)(unsafe.Pointer(&val[0])), C.size_t(len(val)),
k, C.size_t(len(key)),
v, C.size_t(len(val)),
C.MDBX_put_flags_t(flags),
)
return operrno("mdbx_cursor_put", ret)
Expand All @@ -238,14 +244,14 @@ func (c *Cursor) Put(key, val []byte, flags uint) error {
// avoiding a memcopy. The returned byte slice is only valid in txn's thread,
// before it has terminated.
func (c *Cursor) PutReserve(key []byte, n int, flags uint) ([]byte, error) {
if len(key) == 0 {
return nil, c.putNilKey(flags)
var k *C.char
if len(key) > 0 {
k = (*C.char)(unsafe.Pointer(&key[0]))
}

c.txn.val.iov_len = C.size_t(n)
ret := C.mdbxgo_cursor_put1(
c._c,
(*C.char)(unsafe.Pointer(&key[0])), C.size_t(len(key)),
k, C.size_t(len(key)),
c.txn.val,
C.MDBX_put_flags_t(flags|C.MDBX_RESERVE),
)
Expand All @@ -254,7 +260,7 @@ func (c *Cursor) PutReserve(key []byte, n int, flags uint) ([]byte, error) {
*c.txn.val = C.MDBX_val{}
return nil, err
}
b := getBytes(c.txn.val)
b := castToBytes(c.txn.val)
*c.txn.val = C.MDBX_val{}
return b, nil
}
Expand All @@ -265,18 +271,19 @@ func (c *Cursor) PutReserve(key []byte, n int, flags uint) ([]byte, error) {
//
// See mdb_cursor_put.
func (c *Cursor) PutMulti(key []byte, page []byte, stride int, flags uint) error {
if len(key) == 0 {
return c.putNilKey(flags)
var k *C.char
if len(key) > 0 {
k = (*C.char)(unsafe.Pointer(&key[0]))
}
if len(page) == 0 {
page = []byte{0}
var v *C.char
if len(page) > 0 {
v = (*C.char)(unsafe.Pointer(&page[0]))
}

vn := WrapMulti(page, stride).Len()
ret := C.mdbxgo_cursor_putmulti(
c._c,
(*C.char)(unsafe.Pointer(&key[0])), C.size_t(len(key)),
(*C.char)(unsafe.Pointer(&page[0])), C.size_t(vn), C.size_t(stride),
k, C.size_t(len(key)),
v, C.size_t(vn), C.size_t(stride),
C.MDBX_put_flags_t(flags|C.MDBX_MULTIPLE),
)
return operrno("mdbxgo_cursor_putmulti", ret)
Expand Down
98 changes: 98 additions & 0 deletions mdbx/mdbx_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,108 @@
package mdbx

import (
"bytes"
"fmt"
"testing"
)

func TestEmptyKeysAndValues(t *testing.T) {
env, err1 := NewEnv()
if err1 != nil {
t.Fatalf("Cannot create environment: %s", err1)
}
err1 = env.SetGeometry(-1, -1, 1024*1024, -1, -1, 4096)
if err1 != nil {
t.Fatalf("Cannot set mapsize: %s", err1)
}
path := t.TempDir()
err1 = env.Open(path, 0, 0664)
defer env.Close()
if err1 != nil {
t.Fatalf("Cannot open environment: %s", err1)
}

var db DBI
numEntries := 4
if err := env.Update(func(txn *Txn) (err error) {
db, err = txn.OpenRoot(0)
if err != nil {
panic(err)
}

err = txn.Put(db, nil, []byte{}, NoOverwrite)
if err != nil {
panic(err)
}
err = txn.Put(db, []byte{}, []byte{}, NoOverwrite)
if err == nil { //expect err: MDBX_KEYEXIST
panic(err)
}
err = txn.Put(db, []byte{1}, []byte{}, NoOverwrite)
if err != nil {
panic(err)
}
err = txn.Put(db, []byte{2}, nil, NoOverwrite)
if err != nil {
panic(err)
}
err = txn.Put(db, []byte{3}, []byte{1}, NoOverwrite)
if err != nil {
panic(err)
}
return nil
}); err != nil {
t.Fatal(err)
}

stat, err1 := env.Stat()
if err1 != nil {
t.Fatalf("Cannot get stat %s", err1)
} else if stat.Entries != uint64(numEntries) {
t.Errorf("Less entry in the database than expected: %d <> %d", stat.Entries, numEntries)
}
if err := env.View(func(txn *Txn) error {
v, err := txn.Get(db, nil)
if err != nil {
panic(err)
}
if !bytes.Equal(v, []byte{}) {
panic(fmt.Sprintf("%x", v))
}
v, err = txn.Get(db, []byte{})
if err != nil {
panic(err)
}
if !bytes.Equal(v, []byte{}) {
panic(fmt.Sprintf("%x", v))
}
v, err = txn.Get(db, []byte{1})
if err != nil {
panic(err)
}
if !bytes.Equal(v, []byte{}) {
panic(fmt.Sprintf("%x", v))
}
v, err = txn.Get(db, []byte{2})
if err != nil {
panic(err)
}
if !bytes.Equal(v, []byte{}) {
panic(fmt.Sprintf("%x", v))
}
v, err = txn.Get(db, []byte{3})
if err != nil {
panic(err)
}
if !bytes.Equal(v, []byte{1}) {
panic(fmt.Sprintf("%x", v))
}
return nil
}); err != nil {
t.Fatal(err)
}
}

func TestTest1(t *testing.T) {
env, err1 := NewEnv()
if err1 != nil {
Expand Down
Loading

0 comments on commit 7716cdb

Please sign in to comment.