Github user dcelasun commented on a diff in the pull request:
https://github.com/apache/thrift/pull/1440#discussion_r175252297
--- Diff: lib/go/thrift/fast_buffer.go ---
@@ -0,0 +1,257 @@
+package thrift
+
+import (
+ "fmt"
+ "unsafe"
+)
+
+type FastFrameBuffer struct {
+ w *TFramedTransport //
+ b []byte
+ wIdx int // write-offset, reset when Flush
+ frameSize int
+ rIdx int // read-offset, reset when read-new-frame
+ buf [4]byte // only for write&read data-len
+}
+
+func NewFastBuffer(w *TFramedTransport, size int) *FastFrameBuffer {
+ return &FastFrameBuffer{
+ w: w,
+ b: make([]byte, size),
+ rIdx: 0,
+ wIdx: 0,
+ }
+}
+
+func (p *FastFrameBuffer) WritByte(b int8) {
+ if p.wIdx+1 > p.Cap() {
+ p.grow(2*p.Cap() + 1)
+ }
+ p.b[p.wIdx] = byte(b)
+ p.wIdx += 1
+}
+
+func (p *FastFrameBuffer) WriteBytes(b []byte) {
+ if p.wIdx+len(b) > p.Cap() {
+ p.grow(2*p.Cap() + len(b))
+ }
+ copy(p.b[p.wIdx:], b)
+ p.wIdx += len(b)
+}
+
+func (p *FastFrameBuffer) WriteI16(i uint16) {
+ if p.wIdx+2 > p.Cap() {
+ p.grow(2*p.Cap() + 2)
+ }
+ copy(p.b[p.wIdx:], []byte{byte(i >> 8), byte(i)})
+ p.wIdx += 2
+}
+
+func (p *FastFrameBuffer) WriteI32(i uint32) {
+ if p.wIdx+4 > p.Cap() {
+ p.grow(2*p.Cap() + 4)
+ }
+ copy(p.b[p.wIdx:], []byte{byte(i >> 24), byte(i >> 16), byte(i >> 8),
byte(i)})
+ p.wIdx += 4
+}
+
+func (p *FastFrameBuffer) WriteI64(i uint64) {
+ if p.wIdx+8 > p.Cap() {
+ p.grow(2*p.Cap() + 8)
+ }
+ copy(p.b[p.wIdx:], []byte{byte(i >> 56), byte(i >> 48), byte(i >> 40),
byte(i >> 32), byte(i >> 24), byte(i >> 16), byte(i >> 8), byte(i)})
+ p.wIdx += 8
+}
+
+func (p *FastFrameBuffer) WriteString(s string) {
+ if p.wIdx+len(s) > p.Cap() {
+ p.grow(2*p.Cap() + len(s))
+ }
+ copy(p.b[p.wIdx:], str2bytes(s))
+ p.wIdx += len(s)
+}
+
+func (p *FastFrameBuffer) Len() int {
+ return len(p.b)
+}
+
+func (p *FastFrameBuffer) Cap() int {
+ return cap(p.b)
+}
+
+func (p *FastFrameBuffer) Flush() error {
+ p.buf[0] = byte(p.wIdx >> 24)
+ p.buf[1] = byte(p.wIdx >> 16)
+ p.buf[2] = byte(p.wIdx >> 8)
+ p.buf[3] = byte(p.wIdx)
+ _, err := p.w.transport.Write(p.buf[:4])
+
+ if err != nil {
+ return fmt.Errorf("Flush Write-Len failed, err: %v\n", err)
+ }
+ _, err = p.w.transport.Write(p.b[:p.wIdx])
+ if err != nil {
+ return fmt.Errorf("Flush Write-Dat failed, err: %v\n", err)
+ }
+ p.ResetWriter()
+ p.w.transport.Flush()
+ return nil
+}
+
+func (p *FastFrameBuffer) ResetWriter() {
+ p.wIdx = 0
+}
+
+func (p *FastFrameBuffer) ResetReader() {
+ p.rIdx = 0
+}
+
+func (p *FastFrameBuffer) grow(n int) {
+ b := make([]byte, n)
+ copy(b, p.b[0:])
+ p.b = b
+}
+
+func (p *FastFrameBuffer) ReadByte() (c byte, err error) {
+ if p.frameSize == 0 {
+ p.frameSize, err = p.readFrameHeader()
+ if err != nil {
+ return
+ }
+ _, err = p.readAll(p.frameSize)
+ if err != nil {
+ return
+ }
+ }
+ if p.frameSize < 1 {
+ return 0, fmt.Errorf("Not enought frame size %d to read %d
bytes", p.frameSize, 1)
+ }
+ c = p.b[p.rIdx]
+ if err == nil {
+ p.frameSize--
+ p.rIdx += 1
+ }
+ return
+}
+
+// maybe read-bytes means ReadN
+func (p *FastFrameBuffer) ReadN(num int) (b []byte, err error) {
+ if p.frameSize == 0 {
+ p.frameSize, err = p.readFrameHeader()
+ if err != nil {
+ return
+ }
+ _, err = p.readAll(p.frameSize)
+ if err != nil {
+ return
+ }
+ }
+ if p.frameSize < num {
+ return nil, fmt.Errorf("Not enought frame size %d to read %d
bytes", p.frameSize, num)
+ }
+ b = p.b[p.rIdx : p.rIdx+num]
+ p.frameSize = p.frameSize - num
+ if p.frameSize < 0 {
+ return nil, fmt.Errorf("Negative frame size")
+ }
+ p.rIdx += num
+ return b, nil
+}
+
+func (p *FastFrameBuffer) ReadI64() (num int64, err error) {
+ if p.frameSize == 0 {
+ p.frameSize, err = p.readFrameHeader()
+ if err != nil {
+ return
+ }
+ _, err = p.readAll(p.frameSize)
+ if err != nil {
+ return
+ }
+
+ }
+ if p.frameSize < 8 {
+ return 0, fmt.Errorf("Not enought frame size %d to read %d
bytes", p.frameSize, 2)
+ }
+ num = int64(uint64(p.b[p.rIdx+7]) | uint64(p.b[p.rIdx+6])<<8 |
uint64(p.b[p.rIdx+5])<<16 | uint64(p.b[p.rIdx+4])<<24 |
uint64(p.b[p.rIdx+3])<<32 | uint64(p.b[p.rIdx+2])<<40 |
uint64(p.b[p.rIdx+1])<<48 | uint64(p.b[p.rIdx])<<56)
+ p.frameSize = p.frameSize - 8
+ p.rIdx += 8
+ return num, nil
+}
+
+func (p *FastFrameBuffer) ReadI32() (num int32, err error) {
+ if p.frameSize == 0 {
+ p.frameSize, err = p.readFrameHeader()
+ if err != nil {
+ return
+ }
+ _, err = p.readAll(p.frameSize)
+ if err != nil {
+ return
+ }
+ }
+ if p.frameSize < 4 {
+ return 0, fmt.Errorf("Not enought frame size %d to read %d
bytes", p.frameSize, 2)
+ }
+ num = int32(uint32(p.b[p.rIdx+3]) | uint32(p.b[p.rIdx+2])<<8 |
uint32(p.b[p.rIdx+1])<<16 | uint32(p.b[p.rIdx])<<24)
+ p.frameSize = p.frameSize - 4
+ p.rIdx += 4
+ return num, nil
+}
+
+func (p *FastFrameBuffer) ReadI16() (num int16, err error) {
+ if p.frameSize == 0 {
+ p.frameSize, err = p.readFrameHeader()
+ if err != nil {
+ return
+ }
+ _, err = p.readAll(p.frameSize)
+ if err != nil {
+ return
+ }
+ }
+ if p.frameSize < 2 {
+ return 0, fmt.Errorf("Not enought frame size %d to read %d
bytes", p.frameSize, 2)
+ }
+ num = int16(uint16(p.b[p.rIdx+1]) | uint16(p.b[p.rIdx])<<8)
+ p.frameSize = p.frameSize - 2
+ p.rIdx += 2
+ return num, nil
+}
+
+func (p *FastFrameBuffer) readFrameHeader() (int, error) {
+ p.ResetReader()
+ if _, err := p.w.transport.Read(p.buf[:4]); err != nil {
+ return 0, err
+ }
+ frameSize := int(uint32(p.buf[3]) | uint32(p.buf[2])<<8 |
uint32(p.buf[1])<<16 | uint32(p.buf[0])<<24)
+ if frameSize < 0 || frameSize > DEFAULT_MAX_LENGTH {
+ return 0, fmt.Errorf("Incorrect frame size (%d)", frameSize)
+ }
+ return frameSize, nil
+}
+
+// TODO è¿ä¸ªæ¹æ³ æ¯å¦ä¼æé®é¢ï¼ block? or?
--- End diff --
All comments need to be in English.
---