You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by zhiyu-he <gi...@git.apache.org> on 2017/12/09 10:57:30 UTC

[GitHub] thrift pull request #1440: Enhancement binary_protocol with frametransport

GitHub user zhiyu-he opened a pull request:

    https://github.com/apache/thrift/pull/1440

    Enhancement binary_protocol with frametransport

    for frametransport
    write method write data-length to server
    read method read data-length from server
    
    and there are lots of un-usable memory copy & system call 
    
    i optimize this with an simple buffer, manager de write & read
    with the benchmark for write improve 2times & for read improve 3times
    
    link-for testing: https://github.com/zhiyu-he/go_performance/blob/hzy/modify/benchmark/thrift_serializer_test.go

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/ThoseFlowers/thrift OPT/fast_binary_protocol

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/thrift/pull/1440.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #1440
    
----
commit 872f7450d352209e1ee2644ec9a43c74af88137d
Author: hezhiyu <he...@bytedance.com>
Date:   2017-12-08T09:37:32Z

    q
    
    Change-Id: Iba77f4f202575c5c12cd3a490481593b58a35b94

----


---

[GitHub] thrift pull request #1440: Enhancement binary_protocol with frametransport

Posted by dcelasun <gi...@git.apache.org>.
Github user dcelasun commented on a diff in the pull request:

    https://github.com/apache/thrift/pull/1440#discussion_r175252293
  
    --- 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?
    +func (p *FastFrameBuffer) readAll(num int) (int, error) {
    +	// 当容量不足以装下所有数据的时候, 重新申请一下
    +	if cap(p.b) < num {
    +		rbNew := make([]byte, 2*cap(p.b)+num)
    +		copy(rbNew, p.b)
    +		p.b = rbNew
    +	}
    +	var i = 0
    +	for i < num {
    +		l, err := p.w.transport.Read(p.b[i:])
    +		if err != nil {
    +			return 0, err
    +		}
    +		i += l
    +	}
    +	return i, nil
    +}
    +
    +func str2bytes(s string) []byte {
    --- End diff --
    
    At the very minimum, this file needs an `!appengine` build tag and a separate, slower implementation without using `unsafe`, so it can be used in all platforms supported by Go.


---

[GitHub] thrift issue #1440: Enhancement binary_protocol with frametransport

Posted by zhiyu-he <gi...@git.apache.org>.
Github user zhiyu-he commented on the issue:

    https://github.com/apache/thrift/pull/1440
  
    @jeking3 with go programing, [the function call stack may more expensive.](https://github.com/zhiyu-he/go_performance/blob/master/build_in/func_call_test.go)


---

[GitHub] thrift issue #1440: Enhancement binary_protocol with frametransport

Posted by jeking3 <gi...@git.apache.org>.
Github user jeking3 commented on the issue:

    https://github.com/apache/thrift/pull/1440
  
    Transport and Protocols are supposed to be distinct layers in the Thrift architecture; why did you combine the Binary Transport with the Framed Protocol?


---

[GitHub] thrift issue #1440: Enhancement binary_protocol with frametransport

Posted by dcelasun <gi...@git.apache.org>.
Github user dcelasun commented on the issue:

    https://github.com/apache/thrift/pull/1440
  
    From a cursory look, while the performance improvements are decent and only small code changes are needed, this doesn't really fit into our current architecture.
    
    Since the new types don't depend on any unexported types we define, I think this should be a separate library.


---

[GitHub] thrift issue #1440: Enhancement binary_protocol with frametransport

Posted by zhiyu-he <gi...@git.apache.org>.
Github user zhiyu-he commented on the issue:

    https://github.com/apache/thrift/pull/1440
  
    @jeking3 
    but the difference between buffer-transport and frame_transport, is only the data-length.
    i think thrift transport only use for raw-socket read&write.
    
    within golang, it's inefficient and cost more cpu time.
    
     in binary_protocol,  e.g for int64,  int64->temp-buf(binary_protol)->buf(transport-buf)->socket
    this is not go enough for efficiency
    so i want optimize this part。


---

[GitHub] thrift issue #1440: Enhancement binary_protocol with frametransport

Posted by Jens-G <gi...@git.apache.org>.
Github user Jens-G commented on the issue:

    https://github.com/apache/thrift/pull/1440
  
    Plus chinese comments should be english.


---

[GitHub] thrift issue #1440: Enhancement binary_protocol with frametransport

Posted by jeking3 <gi...@git.apache.org>.
Github user jeking3 commented on the issue:

    https://github.com/apache/thrift/pull/1440
  
    @jfarrell could you please look into why Travis CI didn't execute on this pull request?  It wouldn't have mattered, since this PR has no unit test or cross test that engages it at the moment, but still... it should have run a build.


---

[GitHub] thrift pull request #1440: Enhancement binary_protocol with frametransport

Posted by dcelasun <gi...@git.apache.org>.
Github user dcelasun commented on a diff in the pull request:

    https://github.com/apache/thrift/pull/1440#discussion_r175252307
  
    --- 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)
    --- End diff --
    
    s/enought/enough everywhere in the file.


---

[GitHub] thrift pull request #1440: Enhancement binary_protocol with frametransport

Posted by dcelasun <gi...@git.apache.org>.
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.


---

[GitHub] thrift issue #1440: Enhancement binary_protocol with frametransport

Posted by jeking3 <gi...@git.apache.org>.
Github user jeking3 commented on the issue:

    https://github.com/apache/thrift/pull/1440
  
    I would need to see comments from other folks who use thrift go, and also I need to see a linux build pass, so please rebase on master and force push to kick a new build.


---

[GitHub] thrift issue #1440: Enhancement binary_protocol with frametransport

Posted by jeking3 <gi...@git.apache.org>.
Github user jeking3 commented on the issue:

    https://github.com/apache/thrift/pull/1440
  
    My initial take on this is that the conflation of transport and protocol in general is not a good thing for Thrift.  It limits the flexibility to use one interchangeably with something else, but it's hard to overlook a 2x to 3x improvement in performance.  Is there any way some of these techniques could be applied back to the original separate classes for these types?


---