revising aliases filter/s

This commit is contained in:
2025-02-08 16:01:42 -01:06
parent da5a2fb080
commit 6b3d96b980
6 changed files with 81 additions and 104 deletions

View File

@@ -1,6 +1,7 @@
package filter package filter
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"sort" "sort"
@@ -20,7 +21,7 @@ import (
"realy.lol/timestamp" "realy.lol/timestamp"
) )
func Present(i *uint) bo { return i != nil } func Present(i *uint) bool { return i != nil }
// T is the primary query form for requesting events from a nostr relay. // T is the primary query form for requesting events from a nostr relay.
// //
@@ -38,7 +39,7 @@ type T struct {
Tags *tags.T `json:"-,omitempty"` Tags *tags.T `json:"-,omitempty"`
Since *timestamp.T `json:"since,omitempty"` Since *timestamp.T `json:"since,omitempty"`
Until *timestamp.T `json:"until,omitempty"` Until *timestamp.T `json:"until,omitempty"`
Search by `json:"search,omitempty"` Search []byte `json:"search,omitempty"`
Limit *uint `json:"limit,omitempty"` Limit *uint `json:"limit,omitempty"`
} }
@@ -61,40 +62,40 @@ func New() (f *T) {
func (f *T) Clone() (clone *T) { func (f *T) Clone() (clone *T) {
lim := new(uint) lim := new(uint)
*lim = 1 *lim = 1
IDs := *f.IDs _IDs := *f.IDs
Kinds := *f.Kinds _Kinds := *f.Kinds
Authors := *f.Authors _Authors := *f.Authors
Tags := *f.Tags.Clone() _Tags := *f.Tags.Clone()
Since := *f.Since _Since := *f.Since
Until := *f.Until _Until := *f.Until
Search := make(by, len(f.Search)) _Search := make([]byte, len(f.Search))
copy(Search, f.Search) copy(Search, f.Search)
return &T{ return &T{
IDs: &IDs, IDs: &_IDs,
Kinds: &Kinds, Kinds: &_Kinds,
Authors: &Authors, Authors: &_Authors,
Tags: &Tags, Tags: &_Tags,
Since: &Since, Since: &_Since,
Until: &Until, Until: &_Until,
Search: Search, Search: _Search,
Limit: lim, Limit: lim,
} }
} }
var ( var (
IDs = by("ids") IDs = []byte("ids")
Kinds = by("kinds") Kinds = []byte("kinds")
Authors = by("authors") Authors = []byte("authors")
Since = by("since") Since = []byte("since")
Until = by("until") Until = []byte("until")
Limit = by("limit") Limit = []byte("limit")
Search = by("search") Search = []byte("search")
) )
func (f *T) Marshal(dst by) (b by) { func (f *T) Marshal(dst []byte) (b []byte) {
var err er var err error
_ = err _ = err
var first bo var first bool
// sort the fields so they come out the same // sort the fields so they come out the same
f.Sort() f.Sort()
// open parentheses // open parentheses
@@ -219,7 +220,7 @@ func (f *T) Marshal(dst by) (b by) {
return return
} }
func (f *T) Serialize() (b by) { return f.Marshal(nil) } func (f *T) Serialize() (b []byte) { return f.Marshal(nil) }
// states of the unmarshaler // states of the unmarshaler
const ( const (
@@ -232,10 +233,10 @@ const (
afterClose afterClose
) )
func (f *T) Unmarshal(b by) (r by, err er) { func (f *T) Unmarshal(b []byte) (r []byte, err error) {
r = b[:] r = b[:]
var key by var key []byte
var state no var state int
for ; len(r) >= 0; r = r[1:] { for ; len(r) >= 0; r = r[1:] {
// log.I.F("%c", rem[0]) // log.I.F("%c", rem[0])
switch state { switch state {
@@ -267,27 +268,27 @@ func (f *T) Unmarshal(b by) (r by, err er) {
} }
switch key[0] { switch key[0] {
case '#': case '#':
k := make(by, len(key)) k := make([]byte, len(key))
copy(k, key) copy(k, key)
// r = r[1:] // r = r[1:]
switch key[1] { switch key[1] {
case 'e', 'p': case 'e', 'p':
// the tags must all be 64 character hexadecimal // the tags must all be 64 character hexadecimal
var ff []by var ff [][]byte
if ff, r, err = text.UnmarshalHexArray(r, if ff, r, err = text.UnmarshalHexArray(r,
sha256.Size); chk.E(err) { sha256.Size); chk.E(err) {
return return
} }
ff = append([]by{k}, ff...) ff = append([][]byte{k}, ff...)
f.Tags = f.Tags.AppendTags(tag.New(ff...)) f.Tags = f.Tags.AppendTags(tag.New(ff...))
// f.Tags.T = append(f.Tags.T, tag.New(ff...)) // f.Tags.T = append(f.Tags.T, tag.New(ff...))
default: default:
// other types of tags can be anything // other types of tags can be anything
var ff []by var ff [][]byte
if ff, r, err = text.UnmarshalStringArray(r); chk.E(err) { if ff, r, err = text.UnmarshalStringArray(r); chk.E(err) {
return return
} }
ff = append([]by{k}, ff...) ff = append([][]byte{k}, ff...)
f.Tags = f.Tags.AppendTags(tag.New(ff...)) f.Tags = f.Tags.AppendTags(tag.New(ff...))
// f.Tags.T = append(f.Tags.T, tag.New(ff...)) // f.Tags.T = append(f.Tags.T, tag.New(ff...))
} }
@@ -296,7 +297,7 @@ func (f *T) Unmarshal(b by) (r by, err er) {
if len(key) < len(IDs) { if len(key) < len(IDs) {
goto invalid goto invalid
} }
var ff []by var ff [][]byte
if ff, r, err = text.UnmarshalHexArray(r, if ff, r, err = text.UnmarshalHexArray(r,
sha256.Size); chk.E(err) { sha256.Size); chk.E(err) {
return return
@@ -316,7 +317,7 @@ func (f *T) Unmarshal(b by) (r by, err er) {
if len(key) < len(Authors) { if len(key) < len(Authors) {
goto invalid goto invalid
} }
var ff []by var ff [][]byte
if ff, r, err = text.UnmarshalHexArray(r, schnorr.PubKeyBytesLen); chk.E(err) { if ff, r, err = text.UnmarshalHexArray(r, schnorr.PubKeyBytesLen); chk.E(err) {
return return
} }
@@ -352,7 +353,7 @@ func (f *T) Unmarshal(b by) (r by, err er) {
if len(key) < len(Search) { if len(key) < len(Search) {
goto invalid goto invalid
} }
var txt by var txt []byte
if txt, r, err = text.UnmarshalQuoted(r); chk.E(err) { if txt, r, err = text.UnmarshalQuoted(r); chk.E(err) {
return return
} }
@@ -401,11 +402,11 @@ func (f *T) Unmarshal(b by) (r by, err er) {
} }
} }
invalid: invalid:
err = errorf.E("invalid key,\n'%s'\n'%s'", st(b), st(r)) err = errorf.E("invalid key,\n'%s'\n'%s'", string(b), string(r))
return return
} }
func (f *T) Matches(ev *event.T) bo { func (f *T) Matches(ev *event.T) bool {
if ev == nil { if ev == nil {
// log.T.F("nil event") // log.T.F("nil event")
return false return false
@@ -442,10 +443,10 @@ func (f *T) Matches(ev *event.T) bo {
// This hash is generated via the JSON encoded form of the filter, with the Limit field removed. // This hash is generated via the JSON encoded form of the filter, with the Limit field removed.
// This value should be set to zero after all results from a query of stored events, as per // This value should be set to zero after all results from a query of stored events, as per
// NIP-01. // NIP-01.
func (f *T) Fingerprint() (fp uint64, err er) { func (f *T) Fingerprint() (fp uint64, err error) {
lim := f.Limit lim := f.Limit
f.Limit = nil f.Limit = nil
var b by var b []byte
b = f.Marshal(b) b = f.Marshal(b)
h := sha256.Sum256(b) h := sha256.Sum256(b)
hb := h[:] hb := h[:]
@@ -471,7 +472,7 @@ func (f *T) Sort() {
} }
} }
func arePointerValuesEqual[V comparable](a *V, b *V) bo { func arePointerValuesEqual[V comparable](a *V, b *V) bool {
if a == nil && b == nil { if a == nil && b == nil {
return true return true
} }
@@ -481,25 +482,25 @@ func arePointerValuesEqual[V comparable](a *V, b *V) bo {
return false return false
} }
func Equal(a, b *T) bo { func Equal(a, b *T) bool {
if !a.Kinds.Equals(b.Kinds) || if !a.Kinds.Equals(b.Kinds) ||
!a.IDs.Equal(b.IDs) || !a.IDs.Equal(b.IDs) ||
!a.Authors.Equal(b.Authors) || !a.Authors.Equal(b.Authors) ||
a.Tags.Len() != b.Tags.Len() || a.Tags.Len() != b.Tags.Len() ||
!arePointerValuesEqual(a.Since, b.Since) || !arePointerValuesEqual(a.Since, b.Since) ||
!arePointerValuesEqual(a.Until, b.Until) || !arePointerValuesEqual(a.Until, b.Until) ||
!equals(a.Search, b.Search) || !bytes.Equal(a.Search, b.Search) ||
!a.Tags.Equal(b.Tags) { !a.Tags.Equal(b.Tags) {
return false return false
} }
return true return true
} }
func GenFilter() (f *T, err er) { func GenFilter() (f *T, err error) {
f = New() f = New()
n := frand.Intn(16) n := frand.Intn(16)
for _ = range n { for _ = range n {
id := make(by, sha256.Size) id := make([]byte, sha256.Size)
frand.Read(id) frand.Read(id)
f.IDs = f.IDs.Append(id) f.IDs = f.IDs.Append(id)
// f.IDs.Field = append(f.IDs.Field, id) // f.IDs.Field = append(f.IDs.Field, id)
@@ -523,38 +524,38 @@ func GenFilter() (f *T, err er) {
n = a n = a
} }
for i := range n { for i := range n {
p := make(by, 0, schnorr.PubKeyBytesLen*2) p := make([]byte, 0, schnorr.PubKeyBytesLen*2)
p = hex.EncAppend(p, f.Authors.B(i)) p = hex.EncAppend(p, f.Authors.B(i))
} }
for b := 'a'; b <= 'z'; b++ { for b := 'a'; b <= 'z'; b++ {
l := frand.Intn(6) l := frand.Intn(6)
if b == 'e' || b == 'p' { if b == 'e' || b == 'p' {
var idb []by var idb [][]byte
for range l { for range l {
id := make(by, sha256.Size) id := make([]byte, sha256.Size)
frand.Read(id) frand.Read(id)
idb = append(idb, id) idb = append(idb, id)
} }
idb = append([]by{{'#', byte(b)}}, idb...) idb = append([][]byte{{'#', byte(b)}}, idb...)
f.Tags = f.Tags.AppendTags(tag.FromBytesSlice(idb...)) f.Tags = f.Tags.AppendTags(tag.FromBytesSlice(idb...))
// f.Tags.T = append(f.Tags.T, tag.FromBytesSlice(idb...)) // f.Tags.T = append(f.Tags.T, tag.FromBytesSlice(idb...))
} else { } else {
var idb []by var idb [][]byte
for range l { for range l {
bb := make(by, frand.Intn(31)+1) bb := make([]byte, frand.Intn(31)+1)
frand.Read(bb) frand.Read(bb)
id := make(by, 0, len(bb)*2) id := make([]byte, 0, len(bb)*2)
id = hex.EncAppend(id, bb) id = hex.EncAppend(id, bb)
idb = append(idb, id) idb = append(idb, id)
} }
idb = append([]by{{'#', byte(b)}}, idb...) idb = append([][]byte{{'#', byte(b)}}, idb...)
f.Tags = f.Tags.AppendTags(tag.FromBytesSlice(idb...)) f.Tags = f.Tags.AppendTags(tag.FromBytesSlice(idb...))
// f.Tags.T = append(f.Tags.T, tag.FromBytesSlice(idb...)) // f.Tags.T = append(f.Tags.T, tag.FromBytesSlice(idb...))
} }
} }
tn := no(timestamp.Now().I64()) tn := int(timestamp.Now().I64())
f.Since = &timestamp.T{int64(tn - frand.Intn(10000))} f.Since = &timestamp.T{int64(tn - frand.Intn(10000))}
f.Until = timestamp.Now() f.Until = timestamp.Now()
f.Search = by("token search text") f.Search = []byte("token search text")
return return
} }

View File

@@ -1,15 +1,16 @@
package filter package filter
import ( import (
"bytes"
"testing" "testing"
) )
func TestT_MarshalUnmarshal(t *testing.T) { func TestT_MarshalUnmarshal(t *testing.T) {
var err er var err error
const bufLen = 4000000 const bufLen = 4000000
dst := make(by, 0, bufLen) dst := make([]byte, 0, bufLen)
dst1 := make(by, 0, bufLen) dst1 := make([]byte, 0, bufLen)
dst2 := make(by, 0, bufLen) dst2 := make([]byte, 0, bufLen)
for _ = range 20 { for _ = range 20 {
f := New() f := New()
if f, err = GenFilter(); chk.E(err) { if f, err = GenFilter(); chk.E(err) {
@@ -18,13 +19,13 @@ func TestT_MarshalUnmarshal(t *testing.T) {
dst = f.Marshal(dst) dst = f.Marshal(dst)
dst1 = append(dst1, dst...) dst1 = append(dst1, dst...)
// now unmarshal // now unmarshal
var rem by var rem []byte
fa := New() fa := New()
if rem, err = fa.Unmarshal(dst); chk.E(err) { if rem, err = fa.Unmarshal(dst); chk.E(err) {
t.Fatalf("unmarshal error: %v\n%s\n%s", err, dst, rem) t.Fatalf("unmarshal error: %v\n%s\n%s", err, dst, rem)
} }
dst2 = fa.Marshal(nil) dst2 = fa.Marshal(nil)
if !equals(dst1, dst2) { if !bytes.Equal(dst1, dst2) {
t.Fatalf("marshal error: %v\n%s\n%s", err, dst1, dst2) t.Fatalf("marshal error: %v\n%s\n%s", err, dst1, dst2)
} }
dst, dst1, dst2 = dst[:0], dst1[:0], dst2[:0] dst, dst1, dst2 = dst[:0], dst1[:0], dst2[:0]

View File

@@ -1,22 +1,9 @@
package filter package filter
import ( import (
"bytes"
"realy.lol/context"
"realy.lol/lol" "realy.lol/lol"
) )
type (
bo = bool
by = []byte
st = string
er = error
no = int
cx = context.T
)
var ( var (
log, chk, errorf = lol.Main.Log, lol.Main.Check, lol.Main.Errorf log, chk, errorf = lol.Main.Log, lol.Main.Check, lol.Main.Errorf
equals = bytes.Equal
) )

View File

@@ -9,9 +9,9 @@ type T struct {
F []*filter.T F []*filter.T
} }
func Make(l no) *T { return &T{F: make([]*filter.T, l)} } func Make(l int) *T { return &T{F: make([]*filter.T, l)} }
func (f *T) GetFingerprints() (fps []uint64, err er) { func (f *T) GetFingerprints() (fps []uint64, err error) {
for _, ff := range f.F { for _, ff := range f.F {
var fp uint64 var fp uint64
if fp, err = ff.Fingerprint(); chk.E(err) { if fp, err = ff.Fingerprint(); chk.E(err) {
@@ -22,11 +22,11 @@ func (f *T) GetFingerprints() (fps []uint64, err er) {
return return
} }
func (f *T) Len() no { return len(f.F) } func (f *T) Len() int { return len(f.F) }
func New(ff ...*filter.T) (f *T) { return &T{F: ff} } func New(ff ...*filter.T) (f *T) { return &T{F: ff} }
func (f *T) Match(event *event.T) bo { func (f *T) Match(event *event.T) bool {
for _, f := range f.F { for _, f := range f.F {
if f.Matches(event) { if f.Matches(event) {
return true return true
@@ -35,10 +35,10 @@ func (f *T) Match(event *event.T) bo {
return false return false
} }
func (f *T) String() (s st) { return st(f.Marshal(nil)) } func (f *T) String() (s string) { return string(f.Marshal(nil)) }
func (f *T) Marshal(dst by) (b by) { func (f *T) Marshal(dst []byte) (b []byte) {
var err er var err error
_ = err _ = err
b = dst b = dst
b = append(b, '[') b = append(b, '[')
@@ -53,7 +53,7 @@ func (f *T) Marshal(dst by) (b by) {
return return
} }
func (f *T) Unmarshal(b by) (r by, err er) { func (f *T) Unmarshal(b []byte) (r []byte, err error) {
r = b[:] r = b[:]
if len(r) < 1 { if len(r) < 1 {
err = errorf.E("cannot unmarshal nothing") err = errorf.E("cannot unmarshal nothing")
@@ -94,7 +94,7 @@ func (f *T) Unmarshal(b by) (r by, err er) {
return return
} }
func GenFilters(n no) (ff *T, err er) { func GenFilters(n int) (ff *T, err error) {
ff = &T{} ff = &T{}
for _ = range n { for _ = range n {
var f *filter.T var f *filter.T

View File

@@ -1,14 +1,15 @@
package filters package filters
import ( import (
"bytes"
"testing" "testing"
) )
func TestT_MarshalUnmarshal(t *testing.T) { func TestT_MarshalUnmarshal(t *testing.T) {
var err er var err error
dst := make(by, 0, 4000000) dst := make([]byte, 0, 4000000)
dst1 := make(by, 0, len(dst)) dst1 := make([]byte, 0, len(dst))
dst2 := make(by, 0, len(dst)) dst2 := make([]byte, 0, len(dst))
for _ = range 1000 { for _ = range 1000 {
var f1 *T var f1 *T
if f1, err = GenFilters(5); chk.E(err) { if f1, err = GenFilters(5); chk.E(err) {
@@ -18,13 +19,13 @@ func TestT_MarshalUnmarshal(t *testing.T) {
dst = f1.Marshal(dst) dst = f1.Marshal(dst)
dst1 = append(dst1, dst...) dst1 = append(dst1, dst...)
// now unmarshal // now unmarshal
var rem by var rem []byte
f2 := New() f2 := New()
if rem, err = f2.Unmarshal(dst); chk.E(err) { if rem, err = f2.Unmarshal(dst); chk.E(err) {
t.Fatalf("unmarshal error: %v\n%s\n%s", err, dst, rem) t.Fatalf("unmarshal error: %v\n%s\n%s", err, dst, rem)
} }
dst2 = f2.Marshal(dst2) dst2 = f2.Marshal(dst2)
if !equals(dst1, dst2) { if !bytes.Equal(dst1, dst2) {
t.Fatalf("marshal error: %v\n%s\n%s", err, dst1, dst2) t.Fatalf("marshal error: %v\n%s\n%s", err, dst1, dst2)
} }
dst, dst1, dst2 = dst[:0], dst1[:0], dst2[:0] dst, dst1, dst2 = dst[:0], dst1[:0], dst2[:0]

View File

@@ -1,22 +1,9 @@
package filters package filters
import ( import (
"bytes"
"realy.lol/context"
"realy.lol/lol" "realy.lol/lol"
) )
type (
bo = bool
by = []byte
st = string
er = error
no = int
cx = context.T
)
var ( var (
log, chk, errorf = lol.Main.Log, lol.Main.Check, lol.Main.Errorf log, chk, errorf = lol.Main.Log, lol.Main.Check, lol.Main.Errorf
equals = bytes.Equal
) )