@@ -12,7 +12,10 @@ import "io"
1212
1313const defaultBufSize = 4096
1414
15- // A read buffer similar to bufio.Reader but zero-copy-ish
15+ // A buffer which is used for both reading and writing.
16+ // This is possible since communication on each connection is synchronous.
17+ // In other words, we can't write and read simultaneously on the same connection.
18+ // The buffer is similar to bufio.Reader / Writer but zero-copy-ish
1619// Also highly optimized for this particular use case.
1720type buffer struct {
1821 buf []byte
@@ -37,8 +40,11 @@ func (b *buffer) fill(need int) (err error) {
3740 }
3841
3942 // grow buffer if necessary
43+ // TODO: let the buffer shrink again at some point
44+ // Maybe keep the org buf slice and swap back?
4045 if need > len (b .buf ) {
41- newBuf := make ([]byte , need )
46+ // Round up to the next multiple of the default size
47+ newBuf := make ([]byte , ((need / defaultBufSize )+ 1 )* defaultBufSize )
4248 copy (newBuf , b .buf )
4349 b .buf = newBuf
4450 }
@@ -74,3 +80,44 @@ func (b *buffer) readNext(need int) (p []byte, err error) {
7480 b .length -= need
7581 return
7682}
83+
84+ // returns a buffer with the requested size.
85+ // If possible, a slice from the existing buffer is returned.
86+ // Otherwise a bigger buffer is made.
87+ // Only one buffer (total) can be used at a time.
88+ func (b * buffer ) writeBuffer (length int ) []byte {
89+ if b .length > 0 {
90+ return nil
91+ }
92+
93+ // test (cheap) general case first
94+ if length <= defaultBufSize || length <= cap (b .buf ) {
95+ return b .buf [:length ]
96+ }
97+
98+ if length < maxPacketSize {
99+ b .buf = make ([]byte , length )
100+ return b .buf
101+ }
102+ return make ([]byte , length )
103+ }
104+
105+ // shortcut which can be used if the requested buffer is guaranteed to be
106+ // smaller than defaultBufSize
107+ // Only one buffer (total) can be used at a time.
108+ func (b * buffer ) smallWriteBuffer (length int ) []byte {
109+ if b .length == 0 {
110+ return b .buf [:length ]
111+ }
112+ return nil
113+ }
114+
115+ // takeCompleteBuffer returns the complete existing buffer.
116+ // This can be used if the necessary buffer size is unknown.
117+ // Only one buffer (total) can be used at a time.
118+ func (b * buffer ) takeCompleteBuffer () []byte {
119+ if b .length == 0 {
120+ return b .buf
121+ }
122+ return nil
123+ }
0 commit comments