Skip to content

Commit

Permalink
opt: improve the logic of reading data from socket into ring-buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
panjf2000 committed Nov 30, 2021
1 parent 93a2843 commit a7f07b3
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 39 deletions.
4 changes: 2 additions & 2 deletions eventloop_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (el *eventloop) loopOpen(c *conn) error {
}

func (el *eventloop) loopRead(c *conn) error {
n, err := c.inboundBuffer.CopyFromSocket(c.fd, unix.Read)
n, err := c.inboundBuffer.CopyFromSocket(c.fd)
if n == 0 || err != nil {
if err == unix.EAGAIN {
return nil
Expand Down Expand Up @@ -127,7 +127,7 @@ func (el *eventloop) loopRead(c *conn) error {
return nil
}
}
_ = c.inboundBuffer.MoveLeftoverToHead()
_ = c.inboundBuffer.Rewind()
return nil
}

Expand Down
46 changes: 9 additions & 37 deletions pkg/ringbuffer/ring_buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ package ringbuffer
import (
"errors"

"golang.org/x/sys/unix"

"github.com/panjf2000/gnet/internal/toolkit"
"github.com/panjf2000/gnet/pkg/pool/bytebuffer"
)
Expand Down Expand Up @@ -246,8 +248,8 @@ func (rb *RingBuffer) Write(p []byte) (n int, err error) {
// ========================= gnet specific APIs =========================

// CopyFromSocket copies data from a socket fd into ring-buffer.
func (rb *RingBuffer) CopyFromSocket(fd int, read func(int, []byte) (int, error)) (n int, err error) {
n, err = read(fd, rb.buf[rb.w:])
func (rb *RingBuffer) CopyFromSocket(fd int) (n int, err error) {
n, err = unix.Read(fd, rb.buf[rb.w:])
if n > 0 {
rb.isEmpty = false
rb.w += n
Expand All @@ -258,18 +260,18 @@ func (rb *RingBuffer) CopyFromSocket(fd int, read func(int, []byte) (int, error)
return
}

// MoveLeftoverToHead moves the data from its tail to head.
func (rb *RingBuffer) MoveLeftoverToHead() int {
// Rewind moves the data from its tail to head and rewind its pointers of read and write.
func (rb *RingBuffer) Rewind() int {
if rb.IsEmpty() {
rb.Reset()
return 0
}
if rb.w != 0 {
return 0
}
if rb.r < rb.Length() {
rb.grow(rb.Length() + TCPReadBufferSize)
return rb.Length()
if rb.r < rb.size-rb.r {
rb.grow(rb.size + rb.size/2)
return rb.size - rb.r
}
n := copy(rb.buf, rb.buf[rb.r:])
rb.r = 0
Expand Down Expand Up @@ -368,36 +370,6 @@ func (rb *RingBuffer) ByteBuffer() *bytebuffer.ByteBuffer {
return bb
}

// WithByteBuffer combines the available read bytes and the given bytes. It does not move the read pointer and
// only copy the available data.
func (rb *RingBuffer) WithByteBuffer(b []byte) *bytebuffer.ByteBuffer {
if rb.isEmpty {
return &bytebuffer.ByteBuffer{B: b}
} else if rb.w == rb.r {
bb := bytebuffer.Get()
_, _ = bb.Write(rb.buf[rb.r:])
_, _ = bb.Write(rb.buf[:rb.w])
_, _ = bb.Write(b)
return bb
}

bb := bytebuffer.Get()
if rb.w > rb.r {
_, _ = bb.Write(rb.buf[rb.r:rb.w])
_, _ = bb.Write(b)
return bb
}

_, _ = bb.Write(rb.buf[rb.r:])

if rb.w != 0 {
_, _ = bb.Write(rb.buf[:rb.w])
}
_, _ = bb.Write(b)

return bb
}

// IsFull tells if this ring-buffer is full.
func (rb *RingBuffer) IsFull() bool {
return rb.r == rb.w && !rb.isEmpty
Expand Down

0 comments on commit a7f07b3

Please sign in to comment.