Skip to content

Commit

Permalink
chore: add memory-leak test for cross nodes peek (#337)
Browse files Browse the repository at this point in the history
  • Loading branch information
joway authored Jun 10, 2024
1 parent b383e39 commit ae18a62
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
12 changes: 12 additions & 0 deletions nocopy_linkbuffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,18 @@ func (b *UnsafeLinkBuffer) isSingleNode(readN int) (single bool) {
return l >= readN
}

// memorySize return the real memory size in bytes the LinkBuffer occupied
func (b *LinkBuffer) memorySize() (bytes int) {
for node := b.head; node != nil; node = node.next {
bytes += cap(node.buf)
}
for _, c := range b.caches {
bytes += cap(c)
}
bytes += cap(b.cachePeek)
return bytes
}

// ------------------------------------------ implement link node ------------------------------------------

// newLinkBufferNode create or reuse linkBufferNode.
Expand Down
48 changes: 48 additions & 0 deletions nocopy_linkbuffer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package netpoll

import (
"bytes"
"encoding/binary"
"fmt"
"runtime"
"sync/atomic"
Expand Down Expand Up @@ -724,6 +725,53 @@ func TestLinkBufferIndexByte(t *testing.T) {
}
}

func TestLinkBufferPeekOutOfMemory(t *testing.T) {
bufCap := 1024 * 8
bufNodes := 100
magicN := uint64(2024)
buf := NewLinkBuffer(bufCap)
MustTrue(t, buf.IsEmpty())
Equal(t, cap(buf.write.buf), bufCap)
Equal(t, buf.memorySize(), bufCap)

var p []byte
var err error
// write data that cross multi nodes
for n := 0; n < bufNodes; n++ {
p, err = buf.Malloc(bufCap)
MustNil(t, err)
Equal(t, len(p), bufCap)
binary.BigEndian.PutUint64(p, magicN)
}
Equal(t, buf.MallocLen(), bufCap*bufNodes)
buf.Flush()
Equal(t, buf.MallocLen(), 0)

// peak data that in single node
for i := 0; i < 10; i++ {
p, err = buf.Peek(bufCap)
Equal(t, binary.BigEndian.Uint64(p), magicN)
MustNil(t, err)
Equal(t, len(p), bufCap)
Equal(t, buf.memorySize(), bufCap*bufNodes)
}

// peak data that cross nodes
memorySize := 0
for i := 0; i < 1024; i++ {
p, err = buf.Peek(bufCap + 1)
MustNil(t, err)
Equal(t, binary.BigEndian.Uint64(p), magicN)
Equal(t, len(p), bufCap+1)
if memorySize == 0 {
memorySize = buf.memorySize()
t.Logf("after Peek: memorySize=%d", memorySize)
} else {
Equal(t, buf.memorySize(), memorySize)
}
}
}

func BenchmarkStringToSliceByte(b *testing.B) {
b.StopTimer()
s := "hello world"
Expand Down

0 comments on commit ae18a62

Please sign in to comment.