Refactor tag encoder to optimize buffer reuse, simplify tag marshaling, and improve event handling; enhance tests with additional coverage and example validation.

This commit is contained in:
2025-08-22 23:26:11 +01:00
parent 225f949540
commit 7d20a51508
6 changed files with 66 additions and 30 deletions

View File

@@ -111,27 +111,11 @@ func (ev *E) MarshalJSON() (b []byte, err error) {
b = ints.New(ev.Kind).Marshal(b)
b = append(b, `,"`...)
b = append(b, jTags...)
b = append(b, `":[`...)
b = append(b, `":`...)
if ev.Tags != nil {
lts := len(*ev.Tags) - 1
for i, tt := range *ev.Tags {
b = append(b, '[')
lt := len(tt.T) - 1
for j, t := range tt.T {
b = append(b, '"')
b = append(b, t...)
b = append(b, '"')
if j < lt {
b = append(b, ',')
}
}
b = append(b, ']')
if i < lts {
b = append(b, ',')
}
}
b = ev.Tags.Marshal(b)
}
b = append(b, `],"`...)
b = append(b, `,"`...)
b = append(b, jContent...)
b = append(b, `":"`...)
// it can happen the slice has insufficient capacity to hold the content AND
@@ -175,6 +159,7 @@ func (ev *E) UnmarshalJSON(b []byte) (err error) {
goto BetweenKeys
}
}
log.I.F("start")
goto eof
BetweenKeys:
for ; len(b) > 0; b = b[1:] {
@@ -187,6 +172,7 @@ BetweenKeys:
goto InKey
}
}
log.I.F("BetweenKeys")
goto eof
InKey:
for ; len(b) > 0; b = b[1:] {
@@ -196,6 +182,7 @@ InKey:
}
key = append(key, b[0])
}
log.I.F("InKey")
goto eof
InKV:
for ; len(b) > 0; b = b[1:] {
@@ -208,6 +195,7 @@ InKV:
goto InVal
}
}
log.I.F("InKV")
goto eof
InVal:
// Skip whitespace before value
@@ -298,9 +286,11 @@ InVal:
if !utils.FastEqual(jCreatedAt, key) {
goto invalid
}
if b, err = ints.New(0).Unmarshal(b); chk.T(err) {
i := ints.New(0)
if b, err = i.Unmarshal(b); chk.T(err) {
return
}
ev.CreatedAt = i.Int64()
goto BetweenKV
} else {
goto invalid
@@ -315,7 +305,6 @@ BetweenKV:
if isWhitespace(b[0]) {
continue
}
switch {
case len(b) == 0:
return

View File

@@ -1,16 +1,21 @@
package event
import (
"bufio"
"bytes"
"encoding/json"
"testing"
"time"
"lol.mleku.dev/chk"
"lol.mleku.dev/log"
"lukechampine.com/frand"
"next.orly.dev/pkg/encoders/event/examples"
"next.orly.dev/pkg/encoders/hex"
"next.orly.dev/pkg/encoders/tag"
"next.orly.dev/pkg/utils"
"next.orly.dev/pkg/utils/bufpool"
"next.orly.dev/pkg/utils/units"
)
func TestMarshalJSONUnmarshalJSON(t *testing.T) {
@@ -35,13 +40,12 @@ func TestMarshalJSONUnmarshalJSON(t *testing.T) {
`)
ev.Sig = frand.Bytes(64)
// log.I.S(ev)
b, err := ev.MarshalJSON()
// b, err := ev.MarshalJSON()
var err error
var b []byte
if b, err = json.Marshal(ev); chk.E(err) {
t.Fatal(err)
}
if err != nil {
t.Fatal(err)
}
var bc []byte
bc = append(bc, b...)
ev2 := New()
@@ -49,7 +53,7 @@ func TestMarshalJSONUnmarshalJSON(t *testing.T) {
t.Fatal(err)
}
var b2 []byte
if b2, err = ev.MarshalJSON(); err != nil {
if b2, err = json.Marshal(ev2); err != nil {
t.Fatal(err)
}
if !utils.FastEqual(bc, b2) {
@@ -65,5 +69,30 @@ func TestMarshalJSONUnmarshalJSON(t *testing.T) {
}
func TestExamplesCache(t *testing.T) {
scanner := bufio.NewScanner(bytes.NewBuffer(examples.Cache))
scanner.Buffer(make([]byte, 0, 4*units.Mb), 4*units.Mb)
var err error
for scanner.Scan() {
b := scanner.Bytes()
c := bufpool.Get()
c = c[:0]
c = append(c, b...)
ev := New()
if err = ev.UnmarshalJSON(b); chk.E(err) {
t.Fatal(err)
}
var b2 []byte
if b2, err = ev.MarshalJSON(); err != nil {
t.Fatal(err)
}
if !utils.FastEqual(c, b2) {
log.I.F("\n%s\n%s", c, b2)
t.Fatalf("failed to re-marshal back original")
}
ev.Free()
// Don't return scanner.Bytes() to the pool as it's not a buffer we own
// bufpool.PutBytes(b)
bufpool.PutBytes(b2)
bufpool.PutBytes(c)
}
}