github.com/lirm/aeron-go@v0.0.0-20230415210743-920325491dc4/aeron/command/flyweights.go (about)

     1  /*
     2  Copyright 2016 Stanislav Liberman
     3  Copyright (C) 2022 Talos, Inc.
     4  
     5  Licensed under the Apache License, Version 2.0 (the "License");
     6  you may not use this file except in compliance with the License.
     7  You may obtain a copy of the License at
     8  
     9  http://www.apache.org/licenses/LICENSE-2.0
    10  
    11  Unless required by applicable law or agreed to in writing, software
    12  distributed under the License is distributed on an "AS IS" BASIS,
    13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  See the License for the specific language governing permissions and
    15  limitations under the License.
    16  */
    17  
    18  package command
    19  
    20  import (
    21  	"github.com/lirm/aeron-go/aeron/atomic"
    22  	"github.com/lirm/aeron-go/aeron/flyweight"
    23  )
    24  
    25  type CorrelatedMessage struct {
    26  	flyweight.FWBase
    27  
    28  	ClientID      flyweight.Int64Field
    29  	CorrelationID flyweight.Int64Field
    30  }
    31  
    32  func (m *CorrelatedMessage) Wrap(buf *atomic.Buffer, offset int) flyweight.Flyweight {
    33  	pos := offset
    34  	pos += m.ClientID.Wrap(buf, pos)
    35  	pos += m.CorrelationID.Wrap(buf, pos)
    36  
    37  	m.SetSize(pos - offset)
    38  	return m
    39  }
    40  
    41  type ImageMessage struct {
    42  	flyweight.FWBase
    43  
    44  	CorrelationID              flyweight.Int64Field
    45  	SubscriptionRegistrationID flyweight.Int64Field
    46  	StreamID                   flyweight.Int32Field
    47  	Channel                    flyweight.StringField
    48  }
    49  
    50  func (m *ImageMessage) Wrap(buf *atomic.Buffer, offset int) flyweight.Flyweight {
    51  	pos := offset
    52  	pos += m.CorrelationID.Wrap(buf, pos)
    53  	pos += m.SubscriptionRegistrationID.Wrap(buf, pos)
    54  	pos += m.StreamID.Wrap(buf, pos)
    55  	pos += m.Channel.Wrap(buf, pos, m, true)
    56  
    57  	m.SetSize(pos - offset)
    58  	return m
    59  }
    60  
    61  type PublicationMessage struct {
    62  	flyweight.FWBase
    63  
    64  	ClientID      flyweight.Int64Field
    65  	CorrelationID flyweight.Int64Field
    66  	StreamID      flyweight.Int32Field
    67  	Channel       flyweight.StringField
    68  }
    69  
    70  func (m *PublicationMessage) Wrap(buf *atomic.Buffer, offset int) flyweight.Flyweight {
    71  	pos := offset
    72  	pos += m.ClientID.Wrap(buf, pos)
    73  	pos += m.CorrelationID.Wrap(buf, pos)
    74  	pos += m.StreamID.Wrap(buf, pos)
    75  	pos += m.Channel.Wrap(buf, pos, m, true)
    76  
    77  	m.SetSize(pos - offset)
    78  	return m
    79  }
    80  
    81  type SubscriptionMessage struct {
    82  	flyweight.FWBase
    83  
    84  	ClientID                  flyweight.Int64Field
    85  	CorrelationID             flyweight.Int64Field
    86  	RegistrationCorrelationID flyweight.Int64Field
    87  	StreamID                  flyweight.Int32Field
    88  	Channel                   flyweight.StringField
    89  }
    90  
    91  func (m *SubscriptionMessage) Wrap(buf *atomic.Buffer, offset int) flyweight.Flyweight {
    92  	pos := offset
    93  	pos += m.ClientID.Wrap(buf, pos)
    94  	pos += m.CorrelationID.Wrap(buf, pos)
    95  	pos += m.RegistrationCorrelationID.Wrap(buf, pos)
    96  	pos += m.StreamID.Wrap(buf, pos)
    97  	pos += m.Channel.Wrap(buf, pos, m, true)
    98  
    99  	m.SetSize(pos - offset)
   100  	return m
   101  }
   102  
   103  type RemoveMessage struct {
   104  	flyweight.FWBase
   105  
   106  	ClientID       flyweight.Int64Field
   107  	CorrelationID  flyweight.Int64Field
   108  	RegistrationID flyweight.Int64Field
   109  }
   110  
   111  func (m *RemoveMessage) Wrap(buf *atomic.Buffer, offset int) flyweight.Flyweight {
   112  	pos := offset
   113  	pos += m.ClientID.Wrap(buf, pos)
   114  	pos += m.CorrelationID.Wrap(buf, pos)
   115  	pos += m.RegistrationID.Wrap(buf, pos)
   116  
   117  	m.SetSize(pos - offset)
   118  	return m
   119  }
   120  
   121  type DestinationMessage struct {
   122  	flyweight.FWBase
   123  
   124  	ClientID                  flyweight.Int64Field
   125  	CorrelationID             flyweight.Int64Field
   126  	RegistrationCorrelationID flyweight.Int64Field
   127  	Channel                   flyweight.StringField
   128  }
   129  
   130  func (m *DestinationMessage) Wrap(buf *atomic.Buffer, offset int) flyweight.Flyweight {
   131  	pos := offset
   132  	pos += m.ClientID.Wrap(buf, pos)
   133  	pos += m.CorrelationID.Wrap(buf, pos)
   134  	pos += m.RegistrationCorrelationID.Wrap(buf, pos)
   135  	pos += m.Channel.Wrap(buf, pos, m, true)
   136  
   137  	m.SetSize(pos - offset)
   138  	return m
   139  }
   140  
   141  // CounterMessage has to violate the pattern above.  The existing pattern only works either without any variable fields,
   142  // or with exactly one variable field at the end of the message.  CounterMessage has 2 variable fields, requiring
   143  // realignment of the second anytime there are changes to the first.  This pattern is somewhere between the Go pattern
   144  // and the Java/C++ impls' pattern.  At some point, we may want to refactor all the flyweights to match the Java/C++
   145  // pattern.
   146  type CounterMessage struct {
   147  	flyweight.FWBase
   148  
   149  	buf           *atomic.Buffer
   150  	offset        int
   151  	ClientID      flyweight.Int64Field
   152  	CorrelationID flyweight.Int64Field
   153  	CounterTypeID flyweight.Int32Field
   154  	key           flyweight.LengthAndRawDataField
   155  	label         flyweight.LengthAndRawDataField
   156  }
   157  
   158  func (m *CounterMessage) Wrap(buf *atomic.Buffer, offset int) flyweight.Flyweight {
   159  	m.buf = buf
   160  	m.offset = offset
   161  	pos := offset
   162  	pos += m.ClientID.Wrap(buf, pos)
   163  	pos += m.CorrelationID.Wrap(buf, pos)
   164  	pos += m.CounterTypeID.Wrap(buf, pos)
   165  	pos += m.key.Wrap(buf, pos)
   166  	m.wrapLabel()
   167  	m.setSize()
   168  
   169  	return m
   170  }
   171  
   172  func (m *CounterMessage) getLabelOffset() int {
   173  	// Size of the first 3 fixed fields, the length field of the key, and the key buffer itself.
   174  	return 8 + 8 + 4 + 4 + int(m.key.Length())
   175  }
   176  
   177  func (m *CounterMessage) setSize() {
   178  	m.SetSize(m.getLabelOffset() + 4 + int(m.label.Length()))
   179  }
   180  
   181  func (m *CounterMessage) wrapLabel() {
   182  	m.label.Wrap(m.buf, m.offset+m.getLabelOffset())
   183  }
   184  
   185  // Note: If you call this with a buffer that's a different length than the prior buffer, and you don't also call
   186  // CopyLabelBuffer, the underlying data will be corrupt.  This matches the Java impl.
   187  func (m *CounterMessage) CopyKeyBuffer(buffer *atomic.Buffer, offset int32, length int32) {
   188  	m.key.CopyBuffer(buffer, offset, length)
   189  }
   190  
   191  func (m *CounterMessage) CopyLabelBuffer(buffer *atomic.Buffer, offset int32, length int32) {
   192  	m.wrapLabel()
   193  	m.label.CopyBuffer(buffer, offset, length)
   194  	m.setSize()
   195  }
   196  
   197  func (m *CounterMessage) CopyLabelString(label string) {
   198  	m.wrapLabel()
   199  	m.label.CopyString(label)
   200  	m.setSize()
   201  }