Browse Source

Refactor event encoder to handle nil tags gracefully and optimize buffer allocation; update tests for improved coverage and data consistency.

main
mleku 5 months ago
parent
commit
225f949540
No known key found for this signature in database
  1. 8
      pkg/encoders/event/event.go
  2. 24
      pkg/encoders/event/event_test.go

8
pkg/encoders/event/event.go

@ -112,6 +112,7 @@ func (ev *E) MarshalJSON() (b []byte, err error) {
b = append(b, `,"`...) b = append(b, `,"`...)
b = append(b, jTags...) b = append(b, jTags...)
b = append(b, `":[`...) b = append(b, `":[`...)
if ev.Tags != nil {
lts := len(*ev.Tags) - 1 lts := len(*ev.Tags) - 1
for i, tt := range *ev.Tags { for i, tt := range *ev.Tags {
b = append(b, '[') b = append(b, '[')
@ -129,13 +130,18 @@ func (ev *E) MarshalJSON() (b []byte, err error) {
b = append(b, ',') b = append(b, ',')
} }
} }
}
b = append(b, `],"`...) b = append(b, `],"`...)
b = append(b, jContent...) b = append(b, jContent...)
b = append(b, `":"`...) b = append(b, `":"`...)
// it can happen the slice has insufficient capacity to hold the content AND // it can happen the slice has insufficient capacity to hold the content AND
// the signature at this point, because the signature encoder must have // the signature at this point, because the signature encoder must have
// sufficient capacity pre-allocated as it does not append to the buffer. // sufficient capacity pre-allocated as it does not append to the buffer.
// unlike every other encoding function up to this point. // unlike every other encoding function up to this point. This also ensures
// that since the bufpool defaults to 1kb, most events won't have a
// re-allocation required, but if they do, it will be this next one, and it
// integrates properly with the buffer pool, reducing GC pressure and
// avoiding new heap allocations.
if cap(b) < len(b)+len(ev.Content)+7+256+2 { if cap(b) < len(b)+len(ev.Content)+7+256+2 {
b2 := make([]byte, len(b)+len(ev.Content)*2+7+256+2) b2 := make([]byte, len(b)+len(ev.Content)*2+7+256+2)
copy(b2, b) copy(b2, b)

24
pkg/encoders/event/event_test.go

@ -1,10 +1,10 @@
package event package event
import ( import (
"encoding/json"
"testing" "testing"
"time" "time"
"github.com/pkg/profile"
"lol.mleku.dev/chk" "lol.mleku.dev/chk"
"lukechampine.com/frand" "lukechampine.com/frand"
"next.orly.dev/pkg/encoders/hex" "next.orly.dev/pkg/encoders/hex"
@ -13,11 +13,8 @@ import (
"next.orly.dev/pkg/utils/bufpool" "next.orly.dev/pkg/utils/bufpool"
) )
func TestMarshalJSON(t *testing.T) { func TestMarshalJSONUnmarshalJSON(t *testing.T) {
// lol.SetLogLevel("trace") for range 10000 {
prof := profile.Start(profile.MemProfile)
defer prof.Stop()
for range 1000000 {
ev := New() ev := New()
ev.ID = frand.Bytes(32) ev.ID = frand.Bytes(32)
ev.Pubkey = frand.Bytes(32) ev.Pubkey = frand.Bytes(32)
@ -32,18 +29,23 @@ func TestMarshalJSON(t *testing.T) {
}, },
}, },
} }
ev.Content = frand.Bytes(frand.Intn(1024) + 1) ev.Content = []byte(`some text content
with line breaks and tabs and other stuff
`)
ev.Sig = frand.Bytes(64) ev.Sig = frand.Bytes(64)
// log.I.S(ev) // log.I.S(ev)
b, err := ev.MarshalJSON() b, err := ev.MarshalJSON()
if b, err = json.Marshal(ev); chk.E(err) {
t.Fatal(err)
}
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
var bc []byte var bc []byte
bc = append(bc, b...) bc = append(bc, b...)
// log.I.F("%s", bc)
ev2 := New() ev2 := New()
if err = ev2.UnmarshalJSON(b); chk.E(err) { if err = json.Unmarshal(b, ev2); chk.E(err) {
t.Fatal(err) t.Fatal(err)
} }
var b2 []byte var b2 []byte
@ -61,3 +63,7 @@ func TestMarshalJSON(t *testing.T) {
bufpool.PutBytes(bc) bufpool.PutBytes(bc)
} }
} }
func TestExamplesCache(t *testing.T) {
}

Loading…
Cancel
Save