Skip to content

Commit

Permalink
Fix bytes.Clone
Browse files Browse the repository at this point in the history
  • Loading branch information
yzang2019 committed Oct 11, 2023
1 parent b9e0da8 commit 2f60532
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 8 deletions.
9 changes: 6 additions & 3 deletions sc/memiavl/db/iterator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package memiavl

import "bytes"
import (
"bytes"
"github.com/sei-protocol/sei-db/memiavl/utils"
)

type Iterator struct {
// domain of iteration, end is exclusive
Expand Down Expand Up @@ -51,15 +54,15 @@ func (iter *Iterator) Error() error {
// Key implements dbm.Iterator
func (iter *Iterator) Key() []byte {
if !iter.zeroCopy {
return bytes.Clone(iter.key)
return utils.Clone(iter.key)
}
return iter.key
}

// Value implements dbm.Iterator
func (iter *Iterator) Value() []byte {
if !iter.zeroCopy {
return bytes.Clone(iter.value)
return utils.Clone(iter.value)
}
return iter.value
}
Expand Down
3 changes: 2 additions & 1 deletion sc/memiavl/db/persisted_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package memiavl
import (
"bytes"
"crypto/sha256"
"github.com/sei-protocol/sei-db/memiavl/utils"
"sort"
)

Expand Down Expand Up @@ -132,7 +133,7 @@ func (node PersistedNode) Right() Node {
}

func (node PersistedNode) SafeHash() []byte {
return bytes.Clone(node.Hash())
return utils.Clone(node.Hash())
}

func (node PersistedNode) Hash() []byte {
Expand Down
7 changes: 3 additions & 4 deletions sc/memiavl/db/tree.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package memiavl

import (
"bytes"
"crypto/sha256"
"errors"
"fmt"
Expand Down Expand Up @@ -184,7 +183,7 @@ func (t *Tree) GetWithIndex(key []byte) (int64, []byte) {

value, index := t.root.Get(key)
if !t.zeroCopy {
value = bytes.Clone(value)
value = utils.Clone(value)

Check failure on line 186 in sc/memiavl/db/tree.go

View workflow job for this annotation

GitHub Actions / lint

undefined: utils

Check failure on line 186 in sc/memiavl/db/tree.go

View workflow job for this annotation

GitHub Actions / lint

undefined: utils
}
return int64(index), value
}
Expand All @@ -199,8 +198,8 @@ func (t *Tree) GetByIndex(index int64) ([]byte, []byte) {

key, value := t.root.GetByIndex(uint32(index))
if !t.zeroCopy {
key = bytes.Clone(key)
value = bytes.Clone(value)
key = utils.Clone(key)

Check failure on line 201 in sc/memiavl/db/tree.go

View workflow job for this annotation

GitHub Actions / lint

undefined: utils

Check failure on line 201 in sc/memiavl/db/tree.go

View workflow job for this annotation

GitHub Actions / lint

undefined: utils
value = utils.Clone(value)

Check failure on line 202 in sc/memiavl/db/tree.go

View workflow job for this annotation

GitHub Actions / lint

undefined: utils (typecheck)

Check failure on line 202 in sc/memiavl/db/tree.go

View workflow job for this annotation

GitHub Actions / lint

undefined: utils) (typecheck)
}
return key, value
}
Expand Down
19 changes: 19 additions & 0 deletions sc/memiavl/utils/bytes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package utils

// Clone returns a copy of b[:len(b)].
// The result may have additional unused capacity.
// Clone(nil) returns nil.
func Clone(b []byte) []byte {
if b == nil {
return nil
}
return append([]byte{}, b...)
}

// Equal reports whether a and b
// are the same length and contain the same bytes.
// A nil argument is equivalent to an empty slice.
func Equal(a, b []byte) bool {
// Neither cmd/compile nor gccgo allocates for these string conversions.
return string(a) == string(b)
}
37 changes: 37 additions & 0 deletions sc/memiavl/utils/bytes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package utils

import (
"strings"
"testing"
"unsafe"
)

func TestClone(t *testing.T) {
var cloneTests = [][]byte{
[]byte(nil),
[]byte{},
Clone([]byte{}),
[]byte(strings.Repeat("a", 42))[:0],
[]byte(strings.Repeat("a", 42))[:0:0],
[]byte("short"),
[]byte(strings.Repeat("a", 42)),
}
for _, input := range cloneTests {
clone := Clone(input)
if !Equal(clone, input) {
t.Errorf("Clone(%q) = %q; want %q", input, clone, input)
}

if input == nil && clone != nil {
t.Errorf("Clone(%#v) return value should be equal to nil slice.", input)
}

if input != nil && clone == nil {
t.Errorf("Clone(%#v) return value should not be equal to nil slice.", input)
}

if cap(input) != 0 && unsafe.SliceData(input) == unsafe.SliceData(clone) {
t.Errorf("Clone(%q) return value should not reference inputs backing memory.", input)
}
}
}

0 comments on commit 2f60532

Please sign in to comment.