@@ -115,6 +115,20 @@ func (m FieldMap) GetField(tag Tag, parser FieldValueReader) MessageRejectError
115115 return nil
116116}
117117
118+ // GetField parses of a field with Tag tag. Returned reject may indicate the field is not present, or the field value is invalid.
119+ func (m FieldMap ) getFieldNoLock (tag Tag , parser FieldValueReader ) MessageRejectError {
120+ f , ok := m .tagLookup [tag ]
121+ if ! ok {
122+ return ConditionallyRequiredFieldMissing (tag )
123+ }
124+
125+ if err := parser .Read (f [0 ].value ); err != nil {
126+ return IncorrectDataFormatForValue (tag )
127+ }
128+
129+ return nil
130+ }
131+
118132// GetBytes is a zero-copy GetField wrapper for []bytes fields.
119133func (m FieldMap ) GetBytes (tag Tag ) ([]byte , MessageRejectError ) {
120134 m .rwLock .RLock ()
@@ -128,6 +142,16 @@ func (m FieldMap) GetBytes(tag Tag) ([]byte, MessageRejectError) {
128142 return f [0 ].value , nil
129143}
130144
145+ // getBytesNoLock is a lock free zero-copy GetField wrapper for []bytes fields.
146+ func (m FieldMap ) getBytesNoLock (tag Tag ) ([]byte , MessageRejectError ) {
147+ f , ok := m .tagLookup [tag ]
148+ if ! ok {
149+ return nil , ConditionallyRequiredFieldMissing (tag )
150+ }
151+
152+ return f [0 ].value , nil
153+ }
154+
131155// GetBool is a GetField wrapper for bool fields.
132156func (m FieldMap ) GetBool (tag Tag ) (bool , MessageRejectError ) {
133157 var val FIXBoolean
@@ -152,6 +176,21 @@ func (m FieldMap) GetInt(tag Tag) (int, MessageRejectError) {
152176 return int (val ), err
153177}
154178
179+ // GetInt is a lock free GetField wrapper for int fields.
180+ func (m FieldMap ) getIntNoLock (tag Tag ) (int , MessageRejectError ) {
181+ bytes , err := m .getBytesNoLock (tag )
182+ if err != nil {
183+ return 0 , err
184+ }
185+
186+ var val FIXInt
187+ if val .Read (bytes ) != nil {
188+ err = IncorrectDataFormatForValue (tag )
189+ }
190+
191+ return int (val ), err
192+ }
193+
155194// GetTime is a GetField wrapper for utc timestamp fields.
156195func (m FieldMap ) GetTime (tag Tag ) (t time.Time , err MessageRejectError ) {
157196 m .rwLock .RLock ()
@@ -179,6 +218,15 @@ func (m FieldMap) GetString(tag Tag) (string, MessageRejectError) {
179218 return string (val ), nil
180219}
181220
221+ // GetString is a GetField wrapper for string fields.
222+ func (m FieldMap ) getStringNoLock (tag Tag ) (string , MessageRejectError ) {
223+ var val FIXString
224+ if err := m .getFieldNoLock (tag , & val ); err != nil {
225+ return "" , err
226+ }
227+ return string (val ), nil
228+ }
229+
182230// GetGroup is a Get function specific to Group Fields.
183231func (m FieldMap ) GetGroup (parser FieldGroupReader ) MessageRejectError {
184232 m .rwLock .RLock ()
@@ -246,6 +294,13 @@ func (m *FieldMap) Clear() {
246294 }
247295}
248296
297+ func (m * FieldMap ) clearNoLock () {
298+ m .tags = m .tags [0 :0 ]
299+ for k := range m .tagLookup {
300+ delete (m .tagLookup , k )
301+ }
302+ }
303+
249304// CopyInto overwrites the given FieldMap with this one.
250305func (m * FieldMap ) CopyInto (to * FieldMap ) {
251306 m .rwLock .RLock ()
@@ -263,9 +318,6 @@ func (m *FieldMap) CopyInto(to *FieldMap) {
263318}
264319
265320func (m * FieldMap ) add (f field ) {
266- m .rwLock .Lock ()
267- defer m .rwLock .Unlock ()
268-
269321 t := fieldTag (f )
270322 if _ , ok := m .tagLookup [t ]; ! ok {
271323 m .tags = append (m .tags , t )
0 commit comments