github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/logtail/service/response.go (about)

     1  // Copyright 2021 Matrix Origin
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  //	http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package service
    15  
    16  import (
    17  	"math"
    18  	"sync"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/common/morpc"
    21  	"github.com/matrixorigin/matrixone/pkg/pb/logtail"
    22  )
    23  
    24  // LogtailResponse wraps logtail.LogtailResponse.
    25  type LogtailResponse struct {
    26  	logtail.LogtailResponse
    27  }
    28  
    29  var _ morpc.Message = (*LogtailResponse)(nil)
    30  
    31  func (r *LogtailResponse) SetID(id uint64) {
    32  	r.ResponseId = id
    33  }
    34  
    35  func (r *LogtailResponse) GetID() uint64 {
    36  	return r.ResponseId
    37  }
    38  func (r *LogtailResponse) DebugString() string {
    39  	return r.LogtailResponse.String()
    40  }
    41  
    42  func (r *LogtailResponse) Size() int {
    43  	return r.ProtoSize()
    44  }
    45  
    46  // ResponsePool acquires or releases LogtailResponse.
    47  type ResponsePool interface {
    48  	// Acquire fetches item from pool.
    49  	Acquire() *LogtailResponse
    50  
    51  	// Release puts item back to pool.
    52  	Release(*LogtailResponse)
    53  }
    54  
    55  type responsePool struct {
    56  	pool *sync.Pool
    57  }
    58  
    59  func NewResponsePool() ResponsePool {
    60  	return &responsePool{
    61  		pool: &sync.Pool{
    62  			New: func() any {
    63  				return &LogtailResponse{}
    64  			},
    65  		},
    66  	}
    67  }
    68  
    69  func (p *responsePool) Acquire() *LogtailResponse {
    70  	return p.pool.Get().(*LogtailResponse)
    71  }
    72  
    73  func (p *responsePool) Release(resp *LogtailResponse) {
    74  	resp.Reset()
    75  	p.pool.Put(resp)
    76  }
    77  
    78  // LogtailResponseSegment wrps logtail.MessageSegment.
    79  type LogtailResponseSegment struct {
    80  	logtail.MessageSegment
    81  }
    82  
    83  var _ morpc.Message = (*LogtailResponseSegment)(nil)
    84  
    85  func (s *LogtailResponseSegment) SetID(id uint64) {
    86  	s.StreamID = id
    87  }
    88  
    89  func (s *LogtailResponseSegment) GetID() uint64 {
    90  	return s.StreamID
    91  }
    92  
    93  func (s *LogtailResponseSegment) DebugString() string {
    94  	return s.String()
    95  }
    96  
    97  func (s *LogtailResponseSegment) Size() int {
    98  	return s.ProtoSize()
    99  }
   100  
   101  // SegmentPool acquires or releases LogtailResponseSegment.
   102  type SegmentPool interface {
   103  	// Acquire fetches item from pool.
   104  	Acquire() *LogtailResponseSegment
   105  
   106  	// Release puts item back to pool.
   107  	Release(*LogtailResponseSegment)
   108  
   109  	// LeastEffectiveCapacity evaluates least payload limit.
   110  	LeastEffectiveCapacity() int
   111  }
   112  
   113  type segmentPool struct {
   114  	maxMessageSize int
   115  	pool           *sync.Pool
   116  }
   117  
   118  func NewSegmentPool(maxMessageSize int) SegmentPool {
   119  	s := &segmentPool{
   120  		maxMessageSize: maxMessageSize,
   121  		pool: &sync.Pool{
   122  			New: func() any {
   123  				seg := &LogtailResponseSegment{}
   124  				seg.Payload = make([]byte, maxMessageSize)
   125  				return seg
   126  			},
   127  		},
   128  	}
   129  	return s
   130  }
   131  
   132  func (s *segmentPool) Acquire() *LogtailResponseSegment {
   133  	return s.pool.Get().(*LogtailResponseSegment)
   134  }
   135  
   136  func (s *segmentPool) Release(seg *LogtailResponseSegment) {
   137  	buf := seg.Payload
   138  	seg.Reset()
   139  	seg.Payload = buf[:cap(buf)]
   140  	s.pool.Put(seg)
   141  }
   142  
   143  func (s *segmentPool) LeastEffectiveCapacity() int {
   144  	segment := s.Acquire()
   145  	defer s.Release(segment)
   146  
   147  	segment.StreamID = math.MaxUint64
   148  	segment.Sequence = math.MaxInt32
   149  	segment.MaxSequence = math.MaxInt32
   150  	segment.MessageSize = math.MaxInt32
   151  	// Now, maxHeaderSize is 32 bytes.
   152  	maxHeaderSize := segment.ProtoSize() - s.maxMessageSize
   153  
   154  	// Take out reserved size, then effective capacity left.
   155  	return s.maxMessageSize - maxHeaderSize
   156  }