Skip to content

Commit

Permalink
Add size to preamble, check capacity instead of length when encoding
Browse files Browse the repository at this point in the history
* If we don't encode the `size`, it is lost during an encoding-decoding round-trip
* If we don't check capacity, we might reallocate needlessly instead of just growing the slice

Signed-off-by: Derek Collison <derek@nats.io>
  • Loading branch information
neilalexander authored and derekcollison committed Apr 18, 2023
1 parent 9b9159a commit 1a24e95
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 5 deletions.
1 change: 1 addition & 0 deletions server/avl/norace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ func TestNoRaceSeqSetEncodeLarge(t *testing.T) {
logResults("Decode time is %v\n", elapsed)
}
require_True(t, ss.Nodes() == ss2.Nodes())
require_True(t, ss.Size() == ss2.Size())
}

func TestNoRaceSeqSetRelativeSpeed(t *testing.T) {
Expand Down
16 changes: 11 additions & 5 deletions server/avl/seqset.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ const (
// hdrLen
hdrLen = 2
// minimum length of an encoded SequenceSet.
minLen = 2 + 4 // magic + version + num nodes.
minLen = 2 + 8 // magic + version + num nodes + num entries.
)

// EncodeLen returns the bytes needed for encoding.
Expand All @@ -198,8 +198,10 @@ func (ss SequenceSet) EncodeLen() int {
func (ss SequenceSet) Encode(buf []byte) ([]byte, error) {
nn, encLen := ss.Nodes(), ss.EncodeLen()

if len(buf) < encLen {
if cap(buf) < encLen {
buf = make([]byte, encLen)
} else {
buf = buf[:encLen]
}

// TODO(dlc) - Go 1.19 introduced Append to not have to keep track.
Expand All @@ -210,7 +212,8 @@ func (ss SequenceSet) Encode(buf []byte) ([]byte, error) {
buf[0], buf[1] = magic, version
i := hdrLen
le.PutUint32(buf[i:], uint32(nn))
i += 4
le.PutUint32(buf[i+4:], uint32(ss.size))
i += 8
ss.root.nodeIter(func(n *node) {
le.PutUint64(buf[i:], n.base)
i += 8
Expand All @@ -235,7 +238,8 @@ func Decode(buf []byte) (*SequenceSet, error) {
var le = binary.LittleEndian
index := 2
nn := int(le.Uint32(buf[index:]))
index += 4
sz := int(le.Uint32(buf[index+4:]))
index += 8

expectedLen := minLen + (nn * ((numBuckets+1)*8 + 2))
if len(buf) != expectedLen {
Expand All @@ -244,7 +248,9 @@ func Decode(buf []byte) (*SequenceSet, error) {

nodes := make([]node, nn)

var ss SequenceSet
ss := SequenceSet{
size: sz,
}
for i := 0; i < nn; i++ {
n := &nodes[i]
n.base = le.Uint64(buf[index:])
Expand Down

0 comments on commit 1a24e95

Please sign in to comment.