Skip to content

Commit

Permalink
#80 make Buffer.toRelease be typed (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
host6 authored Oct 24, 2024
1 parent 7cc0598 commit e9b5d37
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 33 deletions.
44 changes: 19 additions & 25 deletions dynobuffers.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ type Buffer struct {
isReleased bool
owner *Buffer
builder *flatbuffers.Builder
toRelease []interface{}
toRelease []IRelease
}

type IRelease interface {
Release()
}

// Field describes a Scheme field
Expand All @@ -90,17 +94,18 @@ type Field struct {
}

type fieldToBytes struct {
hasValue bool
value interface{}
isAppend bool
hasValue bool
value interface{}
isAppend bool
isEffectivelyNil bool // value is empty object, array or string -> true. Used in [Buffer.ToBytesNilled]
}

func (m *fieldToBytes) Release() {
if !m.hasValue {
return
}
switch typed := m.value.(type) {
case interface{ Release() }:
case IRelease:
typed.Release()
case []*Buffer:
for _, b := range typed {
Expand All @@ -112,6 +117,7 @@ func (m *fieldToBytes) Release() {
m.value = nil
m.isAppend = false
m.hasValue = false
m.isEffectivelyNil = false
}

// ObjectArray used to iterate over array of nested objects
Expand Down Expand Up @@ -231,10 +237,8 @@ func (b *Buffer) Release() {
return
}
b.releaseFieldsToBytes()
for _, releaseableIntf := range b.toRelease {
if releaseable, ok := releaseableIntf.(interface{ Release() }); ok {
releaseable.Release()
}
for _, releaseable := range b.toRelease {
releaseable.Release()
}
b.isReleased = true
putBuffer(b)
Expand Down Expand Up @@ -331,6 +335,7 @@ func (b *Buffer) getByField(f *Field) interface{} {
func (b *Buffer) getByUOffsetT(f *Field, uOffsetT flatbuffers.UOffsetT) interface{} {
if f.IsArray {
if f.Ft == FieldTypeObject {
// a new copy is created because ObjectArray is iterated by method Next()
arr := getObjectArray()
arr.Buffer = NewBuffer(f.FieldScheme)
arr.Len = b.tab.VectorLen(uOffsetT - b.tab.Pos)
Expand Down Expand Up @@ -584,7 +589,7 @@ func (b *Buffer) set(f *Field, value interface{}) {
}

if m.value != nil {
if releaseable, ok := m.value.(interface{ Release() }); ok {
if releaseable, ok := m.value.(IRelease); ok {
b.toRelease = append(b.toRelease, releaseable)
}
}
Expand Down Expand Up @@ -650,7 +655,7 @@ func (b *Buffer) ToBytesNilled() (res []byte, nilledFields []string, err error)
}
for i := range b.fieldsToBytes {
ftb := &b.fieldsToBytes[i]
if ftb.hasValue && ftb.value == nil {
if ftb.hasValue && (ftb.value == nil || ftb.isEffectivelyNil) {
nilledFields = append(nilledFields, b.Scheme.Fields[i].Name)
}
}
Expand Down Expand Up @@ -1000,7 +1005,6 @@ func (b *Buffer) prepareFieldsToBytes() {
}
}

// if modifiedField is set to non-nil but the value is empty array, object or string -> set fieldToBytes.value = nil to easier calculate nilledFields at ToBytesNilled()
func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, error) {
offsets := getOffsetSlice(len(b.Scheme.Fields))
defer putOffsetSlice(offsets)
Expand All @@ -1022,12 +1026,7 @@ func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, er
if arrayUOffsetT, err = b.encodeArray(bl, f, fieldToBytes.value, toAppendToIntf); err != nil {
return 0, err
}
if arrayUOffsetT == 0 {
if f.Ft == FieldTypeObject {
b.toRelease = append(b.toRelease, fieldToBytes.value)
}
fieldToBytes.value = nil
}
fieldToBytes.isEffectivelyNil = arrayUOffsetT == 0
}
} else {
if uOffsetT := b.getFieldUOffsetTByOrder(f.Order); uOffsetT != 0 {
Expand All @@ -1045,10 +1044,7 @@ func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, er
} else if nestedUOffsetT, err = nestedBuffer.encodeBuffer(bl); err != nil {
return 0, err
}
if nestedUOffsetT == 0 {
b.toRelease = append(b.toRelease, fieldToBytes.value)
fieldToBytes.value = nil
}
fieldToBytes.isEffectivelyNil = nestedUOffsetT == 0
}
} else {
if uOffsetT := b.getFieldUOffsetTByOrder(f.Order); uOffsetT != 0 {
Expand All @@ -1074,9 +1070,7 @@ func (b *Buffer) encodeBuffer(bl *flatbuffers.Builder) (flatbuffers.UOffsetT, er
default:
return 0, fmt.Errorf("string required but %#v provided for field %s", stringFieldToBytes.value, f.QualifiedName())
}
if stringUOffsetT == 0 {
stringFieldToBytes.value = nil
}
stringFieldToBytes.isEffectivelyNil = stringUOffsetT == 0

}
} else {
Expand Down
18 changes: 10 additions & 8 deletions dynobuffers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1175,14 +1175,16 @@ func TestApplyMapArrays(t *testing.T) {
"intsObj": nil,
},
{
"ints": []int32{},
"longs": []int64{},
"floats": []float32{},
"doubles": []float64{},
"strings": []string{},
"boolTrues": []bool{},
"bytes": []byte{},
"intsObj": []interface{}{},
"ints": []int32{},
"longs": []int64{},
"floats": []float32{},
"doubles": []float64{},
"strings": []string{},
"boolTrues": []bool{},
"boolFalses": []bool{},
"bytes": []byte{},
"bytesBase64": "",
"intsObj": []interface{}{},
},
}
for _, m := range ms {
Expand Down

0 comments on commit e9b5d37

Please sign in to comment.