diff --git a/benchmarks/encodings/parquet/parquet.go b/benchmarks/encodings/parquet/parquet.go index 6519dcca..0bcc0fb5 100644 --- a/benchmarks/encodings/parquet/parquet.go +++ b/benchmarks/encodings/parquet/parquet.go @@ -128,11 +128,10 @@ func (d *Encoding) Encode(data encodings.InMemoryData) ([]byte, error) { func convertAttrs(attrs *otelstef.Attributes) (r []Attribute) { for i := 0; i < attrs.Len(); i++ { - attr := attrs.At(i) r = append( r, Attribute{ - Key: attr.Key(), - Value: string(attr.Value().String()), + Key: attrs.Key(i), + Value: string(attrs.Value(i).String()), }, ) } diff --git a/benchmarks/encodings/parquet/parquetz.go b/benchmarks/encodings/parquet/parquetz.go index 794c56b9..99f9fad2 100644 --- a/benchmarks/encodings/parquet/parquetz.go +++ b/benchmarks/encodings/parquet/parquetz.go @@ -211,11 +211,10 @@ func (d *EncodingZ) Encode(data encodings.InMemoryData) ([]byte, error) { func convertAttrsZ(attrs *otelstef.Attributes) (r []AttributeZ) { for i := 0; i < attrs.Len(); i++ { - attr := attrs.At(i) r = append( r, AttributeZ{ - Key: attr.Key(), - Value: string(attr.Value().String()), + Key: attrs.Key(i), + Value: string(attrs.Value(i).String()), }, ) } diff --git a/examples/jsonl/internal/jsonstef/jsonobject.go b/examples/jsonl/internal/jsonstef/jsonobject.go index 2f5da896..3544f488 100644 --- a/examples/jsonl/internal/jsonstef/jsonobject.go +++ b/examples/jsonl/internal/jsonstef/jsonobject.go @@ -28,14 +28,6 @@ type JsonObjectElem struct { value JsonValue } -func (e *JsonObjectElem) Key() string { - return e.key -} - -func (e *JsonObjectElem) Value() *JsonValue { - return &e.value -} - func (m *JsonObject) init(parentModifiedFields *modifiedFields, parentModifiedBit uint64) { m.modifiedElems.init(parentModifiedFields, parentModifiedBit) } @@ -72,11 +64,6 @@ func (m *JsonObject) Len() int { return len(m.elems) } -// At returns element at index i. -func (m *JsonObject) At(i int) *JsonObjectElem { - return &m.elems[i] -} - func (m *JsonObject) ensureLen(newLen int) { oldLen := len(m.elems) if newLen != oldLen { @@ -156,6 +143,14 @@ func (m *JsonObject) computeDiff(val *JsonObject) (ret bool) { return ret } +func (m *JsonObject) Key(i int) string { + return m.elems[i].key +} + +func (m *JsonObject) Value(i int) *JsonValue { + return &m.elems[i].value +} + // SetKey sets the key of the element at index i. func (m *JsonObject) SetKey(i int, k string) { if m.elems[i].key != k { diff --git a/examples/jsonl/json2stef.go b/examples/jsonl/json2stef.go index da46111e..6218c3b7 100644 --- a/examples/jsonl/json2stef.go +++ b/examples/jsonl/json2stef.go @@ -29,7 +29,7 @@ func convertToJsonValue(src interface{}, dst *jsonstef.JsonValue) { for _, k := range keys { obj.SetKey(i, k) - convertToJsonValue(v[k], obj.At(i).Value()) + convertToJsonValue(v[k], obj.Value(i)) i++ } //obj.Sort() diff --git a/examples/profile/internal/profile/labels.go b/examples/profile/internal/profile/labels.go index 947b4a90..07830fb4 100644 --- a/examples/profile/internal/profile/labels.go +++ b/examples/profile/internal/profile/labels.go @@ -28,14 +28,6 @@ type LabelsElem struct { value LabelValue } -func (e *LabelsElem) Key() string { - return e.key -} - -func (e *LabelsElem) Value() *LabelValue { - return &e.value -} - func (m *Labels) init(parentModifiedFields *modifiedFields, parentModifiedBit uint64) { m.modifiedElems.init(parentModifiedFields, parentModifiedBit) } @@ -72,11 +64,6 @@ func (m *Labels) Len() int { return len(m.elems) } -// At returns element at index i. -func (m *Labels) At(i int) *LabelsElem { - return &m.elems[i] -} - func (m *Labels) ensureLen(newLen int) { oldLen := len(m.elems) if newLen != oldLen { @@ -156,6 +143,14 @@ func (m *Labels) computeDiff(val *Labels) (ret bool) { return ret } +func (m *Labels) Key(i int) string { + return m.elems[i].key +} + +func (m *Labels) Value(i int) *LabelValue { + return &m.elems[i].value +} + // SetKey sets the key of the element at index i. func (m *Labels) SetKey(i int, k string) { if m.elems[i].key != k { diff --git a/examples/profile/pprof2stef.go b/examples/profile/pprof2stef.go index a912b704..f5e60965 100644 --- a/examples/profile/pprof2stef.go +++ b/examples/profile/pprof2stef.go @@ -125,7 +125,7 @@ func (c *pprof2stef) convertSample(srcSample *profile.Sample, srcProf *profile.P for key, values := range srcSample.Label { for _, value := range values { dstLabels.SetKey(labelIndex, key) - dstLabelValue := dstLabels.At(labelIndex).Value() + dstLabelValue := dstLabels.Value(labelIndex) dstLabelValue.SetStr(value) labelIndex++ } @@ -135,7 +135,7 @@ func (c *pprof2stef) convertSample(srcSample *profile.Sample, srcProf *profile.P for key, values := range srcSample.NumLabel { for _, value := range values { dstLabels.SetKey(labelIndex, key) - dstLabelValue := dstLabels.At(labelIndex).Value() + dstLabelValue := dstLabels.Value(labelIndex) dstLabelValue.SetType(stefprofile.LabelValueTypeNum) numValue := dstLabelValue.Num() numValue.SetVal(value) diff --git a/examples/profile/stef2pprof.go b/examples/profile/stef2pprof.go index 352bc3cb..783e7f51 100644 --- a/examples/profile/stef2pprof.go +++ b/examples/profile/stef2pprof.go @@ -170,8 +170,8 @@ func convertStefToPprof(src io.Reader) (*profile.Profile, error) { stefLabels := reader.Record.Labels() for i := 0; i < stefLabels.Len(); i++ { - key := stefLabels.At(i).Key() - stefLabelValue := stefLabels.At(i).Value() + key := stefLabels.Key(i) + stefLabelValue := stefLabels.Value(i) if stefLabelValue.Type() == stefprofile.LabelValueTypeStr { value := stefLabelValue.Str() diff --git a/go/otel/manual_test.go b/go/otel/manual_test.go index c772639e..11ab0967 100644 --- a/go/otel/manual_test.go +++ b/go/otel/manual_test.go @@ -139,7 +139,7 @@ func mapToTef(m map[string]any, out *otelstef.Attributes) { sort.Strings(keys) for _, k := range keys { - valueToTef(m[k], out.At(i).Value()) + valueToTef(m[k], out.Value(i)) out.SetKey(i, k) i++ } @@ -184,7 +184,7 @@ func valueToTef(v any, into *otelstef.AnyValue) { i := 0 for k, v := range val { kvList.SetKey(i, k) - valueToTef(v, kvList.At(i).Value()) + valueToTef(v, kvList.Value(i)) } default: @@ -196,9 +196,8 @@ func tefToMap(in *otelstef.Attributes) map[string]any { out := map[string]any{} for i := 0; i < in.Len(); i++ { - kv := in.At(i) - val := tefToValue(kv.Value()) - out[kv.Key()] = val + val := tefToValue(in.Value(i)) + out[in.Key(i)] = val } return out } @@ -236,9 +235,8 @@ func tefToValue(src *otelstef.AnyValue) any { values := map[string]any{} kvList := src.KVList() for i := 0; i < kvList.Len(); i++ { - pair := kvList.At(i) - val := tefToValue(pair.Value()) - values[pair.Key()] = val + val := tefToValue(kvList.Value(i)) + values[kvList.Key(i)] = val } return values @@ -410,7 +408,7 @@ func TestLargeMultimap(t *testing.T) { attrs.EnsureLen(attrCount) for i := 0; i < attrCount; i++ { attrs.SetKey(i, strconv.Itoa(i)) - attrs.At(i).Value().SetInt64(int64(i)) + attrs.Value(i).SetInt64(int64(i)) } var attrs1Copy otelstef.Attributes attrs1Copy.CopyFrom(attrs) @@ -420,7 +418,7 @@ func TestLargeMultimap(t *testing.T) { // Modify one key. This normally would result in differential encoding // but since the multimap is large it will use full encoding. This is // precisely the case that this test verifies. - attrs.At(0).Value().SetString("abc") + attrs.Value(0).SetString("abc") var attrs2Copy otelstef.Attributes attrs2Copy.CopyFrom(attrs) err = w.Write() diff --git a/go/otel/otelstef/attributes.go b/go/otel/otelstef/attributes.go index 28a1110e..43074a9b 100644 --- a/go/otel/otelstef/attributes.go +++ b/go/otel/otelstef/attributes.go @@ -28,14 +28,6 @@ type AttributesElem struct { value AnyValue } -func (e *AttributesElem) Key() string { - return e.key -} - -func (e *AttributesElem) Value() *AnyValue { - return &e.value -} - func (m *Attributes) init(parentModifiedFields *modifiedFields, parentModifiedBit uint64) { m.modifiedElems.init(parentModifiedFields, parentModifiedBit) } @@ -72,11 +64,6 @@ func (m *Attributes) Len() int { return len(m.elems) } -// At returns element at index i. -func (m *Attributes) At(i int) *AttributesElem { - return &m.elems[i] -} - func (m *Attributes) ensureLen(newLen int) { oldLen := len(m.elems) if newLen != oldLen { @@ -156,6 +143,14 @@ func (m *Attributes) computeDiff(val *Attributes) (ret bool) { return ret } +func (m *Attributes) Key(i int) string { + return m.elems[i].key +} + +func (m *Attributes) Value(i int) *AnyValue { + return &m.elems[i].value +} + // SetKey sets the key of the element at index i. func (m *Attributes) SetKey(i int, k string) { if m.elems[i].key != k { diff --git a/go/otel/otelstef/envelopeattributes.go b/go/otel/otelstef/envelopeattributes.go index 7ad29236..65fb7d11 100644 --- a/go/otel/otelstef/envelopeattributes.go +++ b/go/otel/otelstef/envelopeattributes.go @@ -28,14 +28,6 @@ type EnvelopeAttributesElem struct { value pkg.Bytes } -func (e *EnvelopeAttributesElem) Key() string { - return e.key -} - -func (e *EnvelopeAttributesElem) Value() pkg.Bytes { - return e.value -} - func (m *EnvelopeAttributes) init(parentModifiedFields *modifiedFields, parentModifiedBit uint64) { m.modifiedElems.init(parentModifiedFields, parentModifiedBit) } @@ -71,11 +63,6 @@ func (m *EnvelopeAttributes) Len() int { return len(m.elems) } -// At returns element at index i. -func (m *EnvelopeAttributes) At(i int) *EnvelopeAttributesElem { - return &m.elems[i] -} - func (m *EnvelopeAttributes) ensureLen(newLen int) { oldLen := len(m.elems) if newLen != oldLen { @@ -153,6 +140,14 @@ func (m *EnvelopeAttributes) Append(k string, v pkg.Bytes) { m.elems = append(m.elems, EnvelopeAttributesElem{key: k, value: v}) } +func (m *EnvelopeAttributes) Key(i int) string { + return m.elems[i].key +} + +func (m *EnvelopeAttributes) Value(i int) pkg.Bytes { + return m.elems[i].value +} + // SetKey sets the key of the element at index i. func (m *EnvelopeAttributes) SetKey(i int, k string) { if m.elems[i].key != k { @@ -163,7 +158,7 @@ func (m *EnvelopeAttributes) SetKey(i int, k string) { // SetValue sets the value of the element at index i. func (m *EnvelopeAttributes) SetValue(i int, v pkg.Bytes) { - if !pkg.BytesEqual(m.elems[i].value, v) { + if m.elems[i].value != v { m.elems[i].value = v m.modifiedElems.markValModified(i) } diff --git a/go/otel/otelstef/keyvaluelist.go b/go/otel/otelstef/keyvaluelist.go index d78436eb..94c91cec 100644 --- a/go/otel/otelstef/keyvaluelist.go +++ b/go/otel/otelstef/keyvaluelist.go @@ -28,14 +28,6 @@ type KeyValueListElem struct { value AnyValue } -func (e *KeyValueListElem) Key() string { - return e.key -} - -func (e *KeyValueListElem) Value() *AnyValue { - return &e.value -} - func (m *KeyValueList) init(parentModifiedFields *modifiedFields, parentModifiedBit uint64) { m.modifiedElems.init(parentModifiedFields, parentModifiedBit) } @@ -72,11 +64,6 @@ func (m *KeyValueList) Len() int { return len(m.elems) } -// At returns element at index i. -func (m *KeyValueList) At(i int) *KeyValueListElem { - return &m.elems[i] -} - func (m *KeyValueList) ensureLen(newLen int) { oldLen := len(m.elems) if newLen != oldLen { @@ -156,6 +143,14 @@ func (m *KeyValueList) computeDiff(val *KeyValueList) (ret bool) { return ret } +func (m *KeyValueList) Key(i int) string { + return m.elems[i].key +} + +func (m *KeyValueList) Value(i int) *AnyValue { + return &m.elems[i].value +} + // SetKey sets the key of the element at index i. func (m *KeyValueList) SetKey(i int, k string) { if m.elems[i].key != k { diff --git a/go/pdata/internal/otlptools/otlpval2tef.go b/go/pdata/internal/otlptools/otlpval2tef.go index c5d7e39d..07f4a34f 100644 --- a/go/pdata/internal/otlptools/otlpval2tef.go +++ b/go/pdata/internal/otlptools/otlpval2tef.go @@ -82,7 +82,7 @@ func (o *Otlp2Stef) MapSorted(m pcommon.Map, out *otelstef.Attributes) { out.EnsureLen(m.Len()) for i := range o.attrElems { - otlpValueToTefAnyValue(o.attrElems[i].val, out.At(i).Value()) + otlpValueToTefAnyValue(o.attrElems[i].val, out.Value(i)) out.SetKey(i, o.attrElems[i].str) } } @@ -92,7 +92,7 @@ func (o *Otlp2Stef) MapUnsorted(m pcommon.Map, out *otelstef.Attributes) { i := 0 m.Range( func(k string, v pcommon.Value) bool { - otlpValueToTefAnyValue(v, out.At(i).Value()) + otlpValueToTefAnyValue(v, out.Value(i)) out.SetKey(i, k) i++ return true @@ -138,7 +138,7 @@ func otlpValueToTefAnyValue(val pcommon.Value, into *otelstef.AnyValue) { val.Map().Range( func(k string, v pcommon.Value) bool { kvList.SetKey(i, k) - otlpValueToTefAnyValue(v, kvList.At(i).Value()) + otlpValueToTefAnyValue(v, kvList.Value(i)) return true }, ) diff --git a/go/pdata/internal/otlptools/tef2otlpval.go b/go/pdata/internal/otlptools/tef2otlpval.go index 0e3d2f40..3f6d94de 100644 --- a/go/pdata/internal/otlptools/tef2otlpval.go +++ b/go/pdata/internal/otlptools/tef2otlpval.go @@ -29,10 +29,8 @@ func TefToOtlpMap(in *otelstef.Attributes, out pcommon.Map) error { //decoder := anyvalue.Decoder{} for i := 0; i < in.Len(); i++ { - kv := in.At(i) - val := out.PutEmpty(kv.Key()) - //decoder.Reset(anyvalue.ImmutableBytes(kv.Value())) - err := tefAnyValueToOtlp(kv.Value(), val) + val := out.PutEmpty(in.Key(i)) + err := tefAnyValueToOtlp(in.Value(i), val) if err != nil { return err } @@ -77,9 +75,8 @@ func tefAnyValueToOtlp(anyVal *otelstef.AnyValue, into pcommon.Value) error { values := into.SetEmptyMap() kvList := anyVal.KVList() for i := 0; i < kvList.Len(); i++ { - pair := kvList.At(i) - val := values.PutEmpty(pair.Key()) - err := tefAnyValueToOtlp(pair.Value(), val) + val := values.PutEmpty(kvList.Key(i)) + err := tefAnyValueToOtlp(kvList.Value(i), val) if err != nil { return err } diff --git a/stefc/generator/multimap.go b/stefc/generator/multimap.go index 6a10dc82..0a715846 100644 --- a/stefc/generator/multimap.go +++ b/stefc/generator/multimap.go @@ -24,10 +24,12 @@ func (g *Generator) getMultiMaps(struc *genStructDef) (ret []*genStructFieldDef) } type MultimapTemplateModel struct { - PackageName string - MultimapName string - Key genMapFieldDef - Value genMapFieldDef + PackageName string + MultimapName string + Key genFieldDef + Value genFieldDef + KeyStoreByPtr bool + ValueStoreByPtr bool } func (g *Generator) oMultimap(multimap *genMapDef) error { diff --git a/stefc/templates/go/multimap.go.tmpl b/stefc/templates/go/multimap.go.tmpl index bd46a0b9..f1e550d1 100644 --- a/stefc/templates/go/multimap.go.tmpl +++ b/stefc/templates/go/multimap.go.tmpl @@ -1,4 +1,4 @@ -{{- /*gotype: github.com/splunk/stef/go/pkg/generator.MultimapTemplateModel*/ -}} +{{- /*gotype: github.com/splunk/stef/stefc/generator.MultimapTemplateModel*/ -}} package {{ .PackageName }} import ( @@ -28,14 +28,6 @@ type {{ .MultimapName }}Elem struct { value {{if .ValueStoreByPtr}}*{{end}}{{.Value.Type.Storage}} } -func (e* {{ .MultimapName }}Elem) Key() {{if.Key.Type.Flags.PassByPtr}}*{{end}}{{.Key.Type.Exported}} { - return {{if and .Key.Type.Flags.PassByPtr (not .KeyStoreByPtr)}}&{{end}}{{.Key.Type.ToExported ("e.key")}} -} - -func (e* {{ .MultimapName }}Elem) Value() {{if.Value.Type.Flags.PassByPtr}}*{{end}}{{.Value.Type.Exported}} { - return {{if and .Value.Type.Flags.PassByPtr (not .ValueStoreByPtr)}}&{{end}}{{.Value.Type.ToExported ("e.value")}} -} - func (m *{{.MultimapName}}) init(parentModifiedFields *modifiedFields, parentModifiedBit uint64) { m.modifiedElems.init(parentModifiedFields, parentModifiedBit) } @@ -77,11 +69,6 @@ func (m *{{.MultimapName}}) Len() int { return len(m.elems) } -// At returns element at index i. -func (m *{{.MultimapName}}) At(i int) *{{.MultimapName}}Elem { - return &m.elems[i] -} - func (m *{{.MultimapName}}) ensureLen(newLen int) { oldLen :=len(m.elems) if newLen!=oldLen { @@ -209,24 +196,72 @@ func (m *{{.MultimapName}}) Append(k {{.Key.Type.Exported}}, v {{.Value.Type.Exp } {{end}} +func (m *{{.MultimapName}}) Key(i int) {{if.Key.Type.Flags.PassByPtr}}*{{end}}{{.Key.Type.Exported}} { + return {{if and .Key.Type.Flags.PassByPtr (not .KeyStoreByPtr)}}&{{end}}{{.Key.Type.ToExported ("m.elems[i].key")}} +} + +func (m *{{.MultimapName}}) Value(i int) {{if.Value.Type.Flags.PassByPtr}}*{{end}}{{.Value.Type.Exported}} { + return {{if and .Value.Type.Flags.PassByPtr (not .ValueStoreByPtr)}}&{{end}}{{.Value.Type.ToExported ("m.elems[i].value")}} +} + {{if .Key.Type.IsPrimitive}} // SetKey sets the key of the element at index i. func (m *{{.MultimapName}}) SetKey(i int, k {{.Key.Type.Exported}}) { - if m.elems[i].key != {{.Key.Type.ToStorage "k"}} { + if m.elems[i].key != {{.Key.Type.ToStorage "k"}} { m.elems[i].key = {{.Key.Type.ToStorage "k"}} m.modifiedElems.markKeyModified(i) } } +{{else if .Key.Type.DictName}} +// SetKey sets the key of the element at index i. +func (m *{{.MultimapName}}) SetKey(i int, k {{if .Key.Type.Flags.PassByPtr}}*{{end}}{{.Key.Type.Exported}}) { + if k.canBeShared() { + // v can be shared by pointer. Compute its difference from current {{.name}} + if {{.Key.Type.ToStorage "k"}}.computeDiff(m.elems[i].key) { + // It is different. Update to it. + m.elems[i].key = {{.Key.Type.ToStorage "k"}} + m.modifiedElems.markKeyModified(i) + } + } else { + if !m.elems[i].key.IsEqual(k) { + if m.elems[i].key.canBeShared() { + m.elems[i].key = m.elems[i].key.Clone(&Allocators{}) + } + m.elems[i].key.CopyFrom({{.Key.Type.ToStorage "k"}}) + m.modifiedElems.markKeyModified(i) + } + } +} {{end}} {{if .Value.Type.IsPrimitive}} // SetValue sets the value of the element at index i. func (m *{{.MultimapName}}) SetValue(i int, v {{.Value.Type.Exported}}) { - if !{{.Value.Type.EqualFunc}}(m.elems[i].value, {{.Value.Type.ToStorage "v"}}) { + if m.elems[i].value != {{.Value.Type.ToStorage "v"}} { m.elems[i].value = {{.Value.Type.ToStorage "v"}} m.modifiedElems.markValModified(i) } } +{{else if .Value.Type.DictName}} +// SetValue sets the value of the element at index i. +func (m *{{.MultimapName}}) SetValue(i int, v {{if.Value.Type.Flags.PassByPtr}}*{{end}}{{.Value.Type.Exported}}) { + if v.canBeShared() { + // v can be shared by pointer. Compute its difference from current {{.name}} + if {{.Value.Type.ToStorage "v"}}.computeDiff(m.elems[i].value) { + // It is different. Update to it. + m.elems[i].value = {{.Value.Type.ToStorage "v"}} + m.modifiedElems.markValModified(i) + } + } else { + if !m.elems[i].value.IsEqual(v) { + if m.elems[i].value.canBeShared() { + m.elems[i].value = m.elems[i].value.Clone(&Allocators{}) + } + m.elems[i].value.CopyFrom({{.Value.Type.ToStorage "v"}}) + m.modifiedElems.markValModified(i) + } + } +} {{end}} // ByteSize returns approximate memory usage in bytes. Used to calculate