3939 "to the current connection or connection pool" )
4040)
4141
42+ var smallBufPool = & sync.Pool {
43+ New : func () interface {} {
44+ return & smallBuf {}
45+ },
46+ }
47+
48+ var slicePool = & sync.Pool {
49+ New : func () interface {} {
50+ return make ([]byte , 1024 )
51+ },
52+ }
53+
4254const (
4355 // Connected signals that connection is established or reestablished.
4456 Connected ConnEventKind = iota + 1
@@ -373,7 +385,6 @@ func Connect(ctx context.Context, dialer Dialer, opts Opts) (conn *Connection, e
373385 }
374386
375387 conn .cond = sync .NewCond (& conn .mutex )
376-
377388 if conn .opts .Reconnect > 0 {
378389 // We don't need these mutex.Lock()/mutex.Unlock() here, but
379390 // runReconnects() expects mutex.Lock() to be set, so it's
@@ -849,7 +860,7 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
849860 go conn .eventer (events )
850861
851862 for atomic .LoadUint32 (& conn .state ) != connClosed {
852- respBytes , err := read (r , conn .lenbuf [:])
863+ respBytes , err := read (r , conn .lenbuf [:], conn )
853864 if err != nil {
854865 err = ClientError {
855866 ErrIoError ,
@@ -858,8 +869,9 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
858869 conn .reconnect (err , c )
859870 return
860871 }
861- buf := smallBuf {b : respBytes }
862- header , code , err := decodeHeader (conn .dec , & buf )
872+ buf := smallBufPool .Get ().(* smallBuf )
873+ buf .b = respBytes
874+ header , code , err := decodeHeader (conn .dec , buf )
863875 if err != nil {
864876 err = ClientError {
865877 ErrProtocolError ,
@@ -871,7 +883,7 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
871883
872884 var fut * Future = nil
873885 if code == iproto .IPROTO_EVENT {
874- if event , err := readWatchEvent (& buf ); err == nil {
886+ if event , err := readWatchEvent (buf ); err == nil {
875887 events <- event
876888 } else {
877889 err = ClientError {
@@ -885,7 +897,7 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
885897 conn .opts .Logger .Report (LogBoxSessionPushUnsupported , conn , header )
886898 } else {
887899 if fut = conn .fetchFuture (header .RequestId ); fut != nil {
888- if err := fut .SetResponse (header , & buf ); err != nil {
900+ if err := fut .SetResponse (header , buf ); err != nil {
889901 fut .SetError (fmt .Errorf ("failed to set response: %w" , err ))
890902 }
891903 conn .markDone (fut )
@@ -1187,7 +1199,7 @@ func (conn *Connection) timeouts() {
11871199 }
11881200}
11891201
1190- func read (r io.Reader , lenbuf []byte ) (response []byte , err error ) {
1202+ func read (r io.Reader , lenbuf []byte , conn ... * Connection ) (response []byte , err error ) {
11911203 var length uint64
11921204
11931205 if _ , err = io .ReadFull (r , lenbuf ); err != nil {
@@ -1211,7 +1223,18 @@ func read(r io.Reader, lenbuf []byte) (response []byte, err error) {
12111223 return
12121224 }
12131225
1214- response = make ([]byte , length )
1226+ if len (conn ) == 0 {
1227+ response = make ([]byte , length )
1228+ } else {
1229+ ptr := slicePool .Get ().([]byte )
1230+ if cap (ptr ) < int (length ) {
1231+ response = make ([]byte , length )
1232+ slicePool .Put (ptr ) // nolint
1233+ } else {
1234+ response = ptr
1235+ response = response [:length ]
1236+ }
1237+ }
12151238 _ , err = io .ReadFull (r , response )
12161239
12171240 return
0 commit comments