@@ -3,6 +3,7 @@ package tarantool
33import (
44 "fmt"
55 "io"
6+ "sync"
67
78 "github.com/tarantool/go-iproto"
89 "github.com/vmihailenco/msgpack/v5"
@@ -12,8 +13,8 @@ import (
1213type Response interface {
1314 // Header returns a response header.
1415 Header () Header
15- // Buffer returns a response buffer.
16- Buffer () * []byte
16+ // Release free responses data and returns buffer's data .
17+ Release () * []byte
1718 // Decode decodes a response.
1819 Decode () ([]interface {}, error )
1920 // DecodeTyped decodes a response into a given container res.
@@ -33,24 +34,54 @@ type baseResponse struct {
3334 err error
3435}
3536
36- func createBaseResponse (header Header , body io.Reader ) (baseResponse , error ) {
37+ var baseResponsePool * sync.Pool = & sync.Pool {
38+ New : func () interface {} {
39+ return & baseResponse {}
40+ },
41+ }
42+
43+ func createBaseResponse (header Header , body io.Reader ) (* baseResponse , error ) {
44+ resp := baseResponsePool .Get ().(* baseResponse )
3745 if body == nil {
38- return baseResponse {header : header }, nil
46+ resp .header = header
47+ return resp , nil
3948 }
4049 if buf , ok := body .(* smallBuf ); ok {
41- return baseResponse {header : header , buf : * buf }, nil
50+ resp .header = header
51+ resp .buf .b = buf .b
52+ resp .buf .p = buf .p
53+ return resp , nil
4254 }
4355 data , err := io .ReadAll (body )
4456 if err != nil {
45- return baseResponse {} , err
57+ return resp , err
4658 }
47- return baseResponse {header : header , buf : smallBuf {b : data }}, nil
59+ resp .header = header
60+ resp .buf .b = data
61+ return resp , nil
62+ }
63+
64+ func (resp * baseResponse ) clear () * []byte {
65+ resp .header .RequestId , resp .header .Error = 0 , 0
66+ resp .data = nil
67+ resp .buf .b = resp .buf .b [:0 ]
68+ resp .buf .p = 0
69+ resp .decoded = false
70+ resp .decodedTyped = false
71+ resp .err = nil
72+ return & resp .buf .b
73+ }
74+
75+ func (resp * baseResponse ) Release () * []byte {
76+ ptr := resp .clear ()
77+ baseResponsePool .Put (resp )
78+ return ptr
4879}
4980
5081// DecodeBaseResponse parse response header and body.
5182func DecodeBaseResponse (header Header , body io.Reader ) (Response , error ) {
5283 resp , err := createBaseResponse (header , body )
53- return & resp , err
84+ return resp , err
5485}
5586
5687// SelectResponse is used for the select requests.
@@ -659,8 +690,39 @@ func (resp *baseResponse) Header() Header {
659690 return resp .header
660691}
661692
662- func (resp * baseResponse ) Buffer () * []byte {
663- return & resp .buf .b
693+ var selectResponsePool * sync.Pool = & sync.Pool {
694+ New : func () interface {} {
695+ return & SelectResponse {}
696+ },
697+ }
698+
699+ func createSelectResponse (header Header , body io.Reader ) (* SelectResponse , error ) {
700+ resp := selectResponsePool .Get ().(* SelectResponse )
701+ if body == nil {
702+ resp .header = header
703+ return resp , nil
704+ }
705+ if buf , ok := body .(* smallBuf ); ok {
706+ resp .header = header
707+ resp .buf .b = buf .b
708+ resp .buf .p = buf .p
709+ return resp , nil
710+ }
711+ data , err := io .ReadAll (body )
712+ if err != nil {
713+ return resp , err
714+ }
715+ resp .header = header
716+ resp .buf .b = data
717+ return resp , nil
718+ }
719+
720+ func (resp * SelectResponse ) Release () * []byte {
721+ ptr := resp .baseResponse .clear ()
722+ resp .pos = resp .pos [:0 ]
723+
724+ selectResponsePool .Put (resp )
725+ return ptr
664726}
665727
666728// Pos returns a position descriptor of the last selected tuple for the SelectResponse.
0 commit comments