Skip to content

Commit

Permalink
#78 eliminate fieldToBytes.isReleased (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
host6 authored Oct 23, 2024
1 parent 6756857 commit 7cc0598
Showing 1 changed file with 27 additions and 31 deletions.
58 changes: 27 additions & 31 deletions dynobuffers.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,13 @@ type Field struct {
}

type fieldToBytes struct {
hasValue bool
value interface{}
isAppend bool
isReleased bool // Allows to reuse the `fieldToBytes` instance instead of `fieldToBytes[i] = nil` on release modified fields
hasValue bool
value interface{}
isAppend bool
}

func (m *fieldToBytes) Release() {
if m.isReleased {
if !m.hasValue {
return
}
switch typed := m.value.(type) {
Expand All @@ -112,7 +111,7 @@ func (m *fieldToBytes) Release() {
}
m.value = nil
m.isAppend = false
m.isReleased = true
m.hasValue = false
}

// ObjectArray used to iterate over array of nested objects
Expand Down Expand Up @@ -244,10 +243,7 @@ func (b *Buffer) Release() {
func (b *Buffer) releaseFieldsToBytes() {
for idx := range b.fieldsToBytes {
m := &b.fieldsToBytes[idx]
if m.hasValue {
m.hasValue = false
m.Release()
}
m.Release()
}
}

Expand Down Expand Up @@ -362,7 +358,7 @@ func (b *Buffer) getByUOffsetT(f *Field, uOffsetT flatbuffers.UOffsetT) interfac
case FieldTypeObject:
b.prepareFieldsToBytes()
fieldToBytes := b.fieldsToBytes[f.Order]
if fieldToBytes.hasValue && !fieldToBytes.isReleased {
if fieldToBytes.hasValue {
return fieldToBytes.value
}
res := ReadBuffer(b.tab.Bytes, f.FieldScheme)
Expand All @@ -383,10 +379,12 @@ func (b *Buffer) GetByField(f *Field) interface{} {
// field is scalar -> scalar is returned
// field is an array of scalars -> []T is returned
// field is a nested object -> *dynobuffers.Buffer is returned.
// note: the retuned object will be automatically considered on root.ToBytes. Not necessary to implicitly call root.Set(nestedBuffer)
// note: nested objects from Get() will be released automatically on root release
// note: further Get() on the same nested object field will return the Buffer that was created on the first Get. Safe to call Get() on the same field multiple times
// note: then root.Set(nestedObjectField, <any nestedBuffer or nil>) -> next Get() willl return the value provided to Set()
//
// note: the retuned object will be automatically considered on root.ToBytes. Not necessary to implicitly call root.Set(nestedBuffer)
// note: nested objects from Get() will be released automatically on root release
// note: further Get() on the same nested object field will return the Buffer that was created on the first Get. Safe to call Get() on the same field multiple times
// note: then root.Set(nestedObjectField, <any nestedBuffer or nil>) -> next Get() willl return the value provided to Set()
//
// field is an array of nested objects -> *dynobuffers.ObjectArray is returned.
// field is not set, set to nil or no such field in the Scheme -> nil
// `Get()` will not consider modifications made by Set, Append, ApplyJSONAndToBytes, ApplyMapBuffer, ApplyMap
Expand Down Expand Up @@ -593,7 +591,6 @@ func (b *Buffer) set(f *Field, value interface{}) {

m.value = value
m.isAppend = false
m.isReleased = false
}

// Append appends an array field. toAppend could be a single value or an array of values
Expand All @@ -619,7 +616,6 @@ func (b *Buffer) append(f *Field, toAppend interface{}) {

m.value = toAppend
m.isAppend = true
m.isReleased = false
}

// ApplyMapBuffer modifies Buffer with JSON specified by jsonMap
Expand Down Expand Up @@ -653,8 +649,8 @@ func (b *Buffer) ToBytesNilled() (res []byte, nilledFields []string, err error)
return
}
for i := range b.fieldsToBytes {
mf := &b.fieldsToBytes[i]
if mf.hasValue && !mf.isReleased && mf.value == nil {
ftb := &b.fieldsToBytes[i]
if ftb.hasValue && ftb.value == nil {
nilledFields = append(nilledFields, b.Scheme.Fields[i].Name)
}
}
Expand Down Expand Up @@ -1017,7 +1013,7 @@ func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, er
if f.IsArray {
arrayUOffsetT := flatbuffers.UOffsetT(0)
fieldToBytes := &b.fieldsToBytes[f.Order]
if fieldToBytes.hasValue && !fieldToBytes.isReleased {
if fieldToBytes.hasValue {
if fieldToBytes.value != nil {
var toAppendToIntf interface{} = nil
if fieldToBytes.isAppend {
Expand All @@ -1042,7 +1038,7 @@ func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, er
} else if f.Ft == FieldTypeObject {
nestedUOffsetT := flatbuffers.UOffsetT(0)
fieldToBytes := &b.fieldsToBytes[f.Order]
if fieldToBytes.hasValue && !fieldToBytes.isReleased {
if fieldToBytes.hasValue {
if fieldToBytes.value != nil {
if nestedBuffer, ok := fieldToBytes.value.(*Buffer); !ok {
return 0, fmt.Errorf("nested object required but %#v provided for field %s", fieldToBytes.value, f.QualifiedName())
Expand All @@ -1063,10 +1059,10 @@ func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, er
(*offsets)[f.Order].obj = nestedUOffsetT
} else if f.Ft == FieldTypeString {
stringUOffsetT := flatbuffers.UOffsetT(0)
modifiedStringField := &b.fieldsToBytes[f.Order]
if modifiedStringField.hasValue && !modifiedStringField.isReleased {
if modifiedStringField.value != nil {
switch toWrite := modifiedStringField.value.(type) {
stringFieldToBytes := &b.fieldsToBytes[f.Order]
if stringFieldToBytes.hasValue {
if stringFieldToBytes.value != nil {
switch toWrite := stringFieldToBytes.value.(type) {
case string:
if len(toWrite) > 0 {
stringUOffsetT = bl.CreateString(toWrite)
Expand All @@ -1076,10 +1072,10 @@ func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, er
stringUOffsetT = bl.CreateByteString(toWrite)
}
default:
return 0, fmt.Errorf("string required but %#v provided for field %s", modifiedStringField.value, f.QualifiedName())
return 0, fmt.Errorf("string required but %#v provided for field %s", stringFieldToBytes.value, f.QualifiedName())
}
if stringUOffsetT == 0 {
modifiedStringField.value = nil
stringFieldToBytes.value = nil
}

}
Expand Down Expand Up @@ -1112,7 +1108,7 @@ func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, er
offsetToWrite = (*offsets)[f.Order].obj
default:
fieldToBytes := &b.fieldsToBytes[f.Order]
if fieldToBytes.hasValue && !fieldToBytes.isReleased {
if fieldToBytes.hasValue {
if isSet = fieldToBytes.value != nil; isSet {
if !encodeFixedSizeValue(bl, f, fieldToBytes.value, beforePrepend) {
return 0, fmt.Errorf("wrong value %T(%#v) provided for field %s", fieldToBytes.value, fieldToBytes.value, f.QualifiedName())
Expand Down Expand Up @@ -1778,7 +1774,7 @@ func (b *Buffer) MarshalJSONObject(enc *gojay.Encoder) {
for _, f := range b.Scheme.Fields {
var value interface{}
fieldToBytes := &b.fieldsToBytes[f.Order]
if fieldToBytes.hasValue && !fieldToBytes.isReleased {
if fieldToBytes.hasValue {
value = fieldToBytes.value
} else {
if f.IsArray {
Expand Down Expand Up @@ -1940,7 +1936,7 @@ func (b *Buffer) ToJSONMap() map[string]interface{} {
for _, f := range b.Scheme.Fields {
var storedVal interface{}
fieldToBytes := &b.fieldsToBytes[f.Order]
if fieldToBytes.hasValue && !fieldToBytes.isReleased {
if fieldToBytes.hasValue {
storedVal = fieldToBytes.value
} else {
storedVal = b.getByField(f)
Expand Down Expand Up @@ -2030,7 +2026,7 @@ func (b *Buffer) IterateFields(names []string, callback func(name string, value

func (b *Buffer) IsModified() bool {
for _, fieldToBytes := range b.fieldsToBytes {
if fieldToBytes.hasValue && !fieldToBytes.isReleased {
if fieldToBytes.hasValue {
return true
}
}
Expand Down

0 comments on commit 7cc0598

Please sign in to comment.