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 }