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
@@ -860,8 +871,9 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
860871 conn .reconnect (err , c )
861872 return
862873 }
863- buf := smallBuf {b : respBytes }
864- header , code , err := decodeHeader (conn .dec , & buf )
874+ buf := smallBufPool .Get ().(* smallBuf )
875+ buf .b = respBytes
876+ header , code , err := decodeHeader (conn .dec , buf )
865877 if err != nil {
866878 err = ClientError {
867879 ErrProtocolError ,
@@ -873,7 +885,7 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
873885
874886 var fut * Future = nil
875887 if code == iproto .IPROTO_EVENT {
876- if event , err := readWatchEvent (& buf ); err == nil {
888+ if event , err := readWatchEvent (buf ); err == nil {
877889 events <- event
878890 } else {
879891 err = ClientError {
@@ -887,7 +899,7 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
887899 conn .opts .Logger .Report (LogBoxSessionPushUnsupported , conn , header )
888900 } else {
889901 if fut = conn .fetchFuture (header .RequestId ); fut != nil {
890- if err := fut .SetResponse (header , & buf ); err != nil {
902+ if err := fut .SetResponse (header , buf ); err != nil {
891903 fut .SetError (fmt .Errorf ("failed to set response: %w" , err ))
892904 }
893905 conn .markDone (fut )
@@ -1190,6 +1202,8 @@ func (conn *Connection) timeouts() {
11901202 }
11911203}
11921204
1205+ // read uses args to allocate slices for responses using sync.Pool.
1206+ // data could be released later using Release.
11931207func read (r io.Reader , lenbuf []byte ) (response []byte , err error ) {
11941208 var length uint64
11951209
@@ -1214,7 +1228,14 @@ func read(r io.Reader, lenbuf []byte) (response []byte, err error) {
12141228 return
12151229 }
12161230
1217- response = make ([]byte , length )
1231+ ptr := slicePool .Get ().([]byte )
1232+ if cap (ptr ) < int (length ) {
1233+ response = make ([]byte , length )
1234+ slicePool .Put (ptr ) // nolint
1235+ } else {
1236+ response = ptr
1237+ response = response [:length ]
1238+ }
12181239 _ , err = io .ReadFull (r , response )
12191240
12201241 return
0 commit comments