summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-mangler
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-mangler')
-rw-r--r--vendor/codeberg.org/gruf/go-mangler/LICENSE2
-rw-r--r--vendor/codeberg.org/gruf/go-mangler/README.md20
-rw-r--r--vendor/codeberg.org/gruf/go-mangler/helpers.go49
-rw-r--r--vendor/codeberg.org/gruf/go-mangler/init.go119
-rw-r--r--vendor/codeberg.org/gruf/go-mangler/load.go79
-rw-r--r--vendor/codeberg.org/gruf/go-mangler/mangle.go18
-rw-r--r--vendor/codeberg.org/gruf/go-mangler/manglers.go77
7 files changed, 260 insertions, 104 deletions
diff --git a/vendor/codeberg.org/gruf/go-mangler/LICENSE b/vendor/codeberg.org/gruf/go-mangler/LICENSE
index e4163ae35..dffbdf0c9 100644
--- a/vendor/codeberg.org/gruf/go-mangler/LICENSE
+++ b/vendor/codeberg.org/gruf/go-mangler/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2022 gruf
+Copyright (c) 2023 gruf
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/vendor/codeberg.org/gruf/go-mangler/README.md b/vendor/codeberg.org/gruf/go-mangler/README.md
index c79b87546..d0de88a43 100644
--- a/vendor/codeberg.org/gruf/go-mangler/README.md
+++ b/vendor/codeberg.org/gruf/go-mangler/README.md
@@ -18,21 +18,19 @@ goarch: amd64
pkg: codeberg.org/gruf/go-mangler
cpu: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
BenchmarkMangle
-BenchmarkMangle-8 723278 1593 ns/op 1168 B/op 120 allocs/op
+BenchmarkMangle-8 533011 2003 ns/op 1168 B/op 120 allocs/op
+BenchmarkMangleKnown
+BenchmarkMangleKnown-8 817060 1458 ns/op 1168 B/op 120 allocs/op
BenchmarkJSON
-BenchmarkJSON-8 199360 6116 ns/op 4243 B/op 142 allocs/op
-BenchmarkBinary
-BenchmarkBinary-8 ------ ---- ns/op ---- B/op --- allocs/op
+BenchmarkJSON-8 188637 5899 ns/op 4211 B/op 142 allocs/op
BenchmarkFmt
-BenchmarkFmt-8 168500 7111 ns/op 2256 B/op 161 allocs/op
-BenchmarkKelindarBinary
-BenchmarkKelindarBinary-8 ------ ---- ns/op ---- B/op --- allocs/op
+BenchmarkFmt-8 162735 7053 ns/op 2257 B/op 161 allocs/op
BenchmarkFxmackerCbor
-BenchmarkFxmackerCbor-8 361416 3255 ns/op 1495 B/op 122 allocs/op
+BenchmarkFxmackerCbor-8 362403 3336 ns/op 1496 B/op 122 allocs/op
BenchmarkMitchellhHashStructure
-BenchmarkMitchellhHashStructure-8 117672 10493 ns/op 8443 B/op 961 allocs/op
+BenchmarkMitchellhHashStructure-8 113982 10079 ns/op 8443 B/op 961 allocs/op
BenchmarkCnfStructhash
-BenchmarkCnfStructhash-8 7078 161926 ns/op 288644 B/op 5843 allocs/op
+BenchmarkCnfStructhash-8 7162 167613 ns/op 288619 B/op 5841 allocs/op
PASS
-ok codeberg.org/gruf/go-mangler 14.377s
+ok codeberg.org/gruf/go-mangler 11.352s
``` \ No newline at end of file
diff --git a/vendor/codeberg.org/gruf/go-mangler/helpers.go b/vendor/codeberg.org/gruf/go-mangler/helpers.go
index 0ca4498af..6658fbef4 100644
--- a/vendor/codeberg.org/gruf/go-mangler/helpers.go
+++ b/vendor/codeberg.org/gruf/go-mangler/helpers.go
@@ -5,6 +5,43 @@ import (
"unsafe"
)
+type (
+ // serializing interfacing types.
+ stringer interface{ String() string }
+ binarymarshaler interface{ MarshalBinary() ([]byte, error) }
+ textmarshaler interface{ MarshalText() ([]byte, error) }
+ jsonmarshaler interface{ MarshalJSON() ([]byte, error) }
+)
+
+func append_uint16(b []byte, u uint16) []byte {
+ return append(b, // LE
+ byte(u),
+ byte(u>>8),
+ )
+}
+
+func append_uint32(b []byte, u uint32) []byte {
+ return append(b, // LE
+ byte(u),
+ byte(u>>8),
+ byte(u>>16),
+ byte(u>>24),
+ )
+}
+
+func append_uint64(b []byte, u uint64) []byte {
+ return append(b, // LE
+ byte(u),
+ byte(u>>8),
+ byte(u>>16),
+ byte(u>>24),
+ byte(u>>32),
+ byte(u>>40),
+ byte(u>>48),
+ byte(u>>56),
+ )
+}
+
func deref_ptr_mangler(mangle Mangler, count int) rMangler {
return func(buf []byte, v reflect.Value) []byte {
for i := 0; i < count; i++ {
@@ -43,6 +80,16 @@ func deref_ptr_rmangler(mangle rMangler, count int) rMangler {
}
}
+func array_to_slice_mangler(mangle Mangler) rMangler {
+ return func(buf []byte, v reflect.Value) []byte {
+ // Get slice of whole array
+ v = v.Slice(0, v.Len())
+
+ // Mangle as known slice type
+ return mangle(buf, v.Interface())
+ }
+}
+
func iter_array_mangler(mangle Mangler) rMangler {
return func(buf []byte, v reflect.Value) []byte {
n := v.Len()
@@ -78,7 +125,7 @@ func iter_map_rmangler(kMangle, vMangle rMangler) rMangler {
buf = kMangle(buf, r.Key())
buf = append(buf, ':')
buf = vMangle(buf, r.Value())
- buf = append(buf, '.')
+ buf = append(buf, ',')
}
if v.Len() > 0 {
buf = buf[:len(buf)-1]
diff --git a/vendor/codeberg.org/gruf/go-mangler/init.go b/vendor/codeberg.org/gruf/go-mangler/init.go
new file mode 100644
index 000000000..2c20e6761
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-mangler/init.go
@@ -0,0 +1,119 @@
+package mangler
+
+import (
+ "net"
+ "net/netip"
+ "net/url"
+ "reflect"
+ "time"
+ _ "unsafe"
+)
+
+func init() {
+ // Register standard library performant manglers.
+ Register(reflect.TypeOf(net.IPAddr{}), mangle_ipaddr)
+ Register(reflect.TypeOf(&net.IPAddr{}), mangle_ipaddr_ptr)
+ Register(reflect.TypeOf(netip.Addr{}), mangle_addr)
+ Register(reflect.TypeOf(&netip.Addr{}), mangle_addr_ptr)
+ Register(reflect.TypeOf(netip.AddrPort{}), mangle_addrport)
+ Register(reflect.TypeOf(&netip.AddrPort{}), mangle_addrport_ptr)
+ Register(reflect.TypeOf(time.Time{}), mangle_time)
+ Register(reflect.TypeOf(&time.Time{}), mangle_time_ptr)
+ Register(reflect.TypeOf(url.URL{}), mangle_url)
+ Register(reflect.TypeOf(&url.URL{}), mangle_url_ptr)
+}
+
+//go:linkname time_sec time.(*Time).sec
+func time_sec(*time.Time) int64
+
+//go:linkname time_nsec time.(*Time).nsec
+func time_nsec(*time.Time) int32
+
+//go:linkname time_stripMono time.(*Time).stripMono
+func time_stripMono(*time.Time)
+
+func mangle_url(buf []byte, a any) []byte {
+ u := (*url.URL)(iface_value(a))
+ return append(buf, u.String()...)
+}
+
+func mangle_url_ptr(buf []byte, a any) []byte {
+ if ptr := (*url.URL)(iface_value(a)); ptr != nil {
+ s := ptr.String()
+ buf = append(buf, '1')
+ return append(buf, s...)
+ }
+ buf = append(buf, '0')
+ return buf
+}
+
+func mangle_time(buf []byte, a any) []byte {
+ t := *(*time.Time)(iface_value(a))
+ time_stripMono(&t) // force non-monotonic time value.
+ buf = append_uint64(buf, uint64(time_sec(&t)))
+ buf = append_uint32(buf, uint32(time_nsec(&t)))
+ return buf
+}
+
+func mangle_time_ptr(buf []byte, a any) []byte {
+ if ptr := (*time.Time)(iface_value(a)); ptr != nil {
+ t := *ptr
+ buf = append(buf, '1')
+ time_stripMono(&t) // force non-monotonic time value.
+ buf = append_uint64(buf, uint64(time_sec(&t)))
+ buf = append_uint32(buf, uint32(time_nsec(&t)))
+ return buf
+ }
+ buf = append(buf, '0')
+ return buf
+}
+
+func mangle_ipaddr(buf []byte, a any) []byte {
+ i := *(*net.IPAddr)(iface_value(a))
+ buf = append(buf, i.IP...)
+ buf = append(buf, i.Zone...)
+ return buf
+}
+
+func mangle_ipaddr_ptr(buf []byte, a any) []byte {
+ if ptr := (*net.IPAddr)(iface_value(a)); ptr != nil {
+ buf = append(buf, '1')
+ buf = append(buf, ptr.IP...)
+ buf = append(buf, ptr.Zone...)
+ return buf
+ }
+ buf = append(buf, '0')
+ return buf
+}
+
+func mangle_addr(buf []byte, a any) []byte {
+ i := (*netip.Addr)(iface_value(a))
+ b, _ := i.MarshalBinary()
+ return append(buf, b...)
+}
+
+func mangle_addr_ptr(buf []byte, a any) []byte {
+ if ptr := (*netip.Addr)(iface_value(a)); ptr != nil {
+ buf = append(buf, '1')
+ b, _ := ptr.MarshalBinary()
+ return append(buf, b...)
+ }
+ buf = append(buf, '0')
+ return buf
+}
+
+func mangle_addrport(buf []byte, a any) []byte {
+ i := (*netip.AddrPort)(iface_value(a))
+ b, _ := i.MarshalBinary()
+ return append(buf, b...)
+}
+
+func mangle_addrport_ptr(buf []byte, a any) []byte {
+ if ptr := (*netip.AddrPort)(iface_value(a)); ptr != nil {
+ buf = append(buf, '1')
+ b, _ := ptr.MarshalBinary()
+ return append(buf, b...)
+ }
+ buf = append(buf, '0')
+ return buf
+}
diff --git a/vendor/codeberg.org/gruf/go-mangler/load.go b/vendor/codeberg.org/gruf/go-mangler/load.go
index 20850f55c..752e5d337 100644
--- a/vendor/codeberg.org/gruf/go-mangler/load.go
+++ b/vendor/codeberg.org/gruf/go-mangler/load.go
@@ -1,10 +1,7 @@
package mangler
import (
- "encoding"
- "net/url"
"reflect"
- "time"
)
// loadMangler is the top-most Mangler load function. It guarantees that a Mangler
@@ -13,6 +10,11 @@ func loadMangler(a any, t reflect.Type) Mangler {
// Load mangler function
mng, rmng := load(a, t)
+ if mng != nil {
+ // Use preferred mangler.
+ return mng
+ }
+
if rmng != nil {
// Wrap reflect mangler to handle iface
return func(buf []byte, a any) []byte {
@@ -20,12 +22,8 @@ func loadMangler(a any, t reflect.Type) Mangler {
}
}
- if mng == nil {
- // No mangler function could be determined
- panic("cannot mangle type: " + t.String())
- }
-
- return mng
+ // No mangler function could be determined
+ panic("cannot mangle type: " + t.String())
}
// load will load a Mangler or reflect Mangler for given type and iface 'a'.
@@ -42,41 +40,33 @@ func load(a any, t reflect.Type) (Mangler, rMangler) {
a = v.Interface()
}
- // Check in fast iface type switch
- if mng := loadIface(a); mng != nil {
+ // Check for Mangled implementation.
+ if _, ok := a.(Mangled); ok {
+ return mangle_mangled, nil
+ }
+
+ // Search mangler by reflection.
+ mng, rmng := loadReflect(t)
+ if mng != nil {
return mng, nil
}
- // Search by reflection
- return loadReflect(t)
+ // Prefer iface mangler, else, reflected.
+ return loadIface(a), rmng
}
-// loadIface is used as a first-resort interface{} type switcher loader
-// for types implementing Mangled and providing performant alternative
-// Mangler functions for standard library types to avoid reflection.
+// loadIface is used as a near-last-resort interface{} type switch
+// loader for types implementating other known (slower) functions.
func loadIface(a any) Mangler {
switch a.(type) {
- case Mangled:
- return mangle_mangled
-
- case time.Time:
- return mangle_time
-
- case *time.Time:
- return mangle_time_ptr
-
- case *url.URL:
- return mangle_stringer
-
- case encoding.BinaryMarshaler:
+ case binarymarshaler:
return mangle_binary
-
- // NOTE:
- // we don't just handle ALL fmt.Stringer types as often
- // the output is large and unwieldy and this interface
- // switch is for types it would be faster to avoid reflection.
- // If they want better performance they can implement Mangled{}.
-
+ case stringer:
+ return mangle_stringer
+ case textmarshaler:
+ return mangle_text
+ case jsonmarshaler:
+ return mangle_json
default:
return nil
}
@@ -159,18 +149,19 @@ func loadReflectPtr(et reflect.Type) (Mangler, rMangler) {
}
if et.Kind() == reflect.Array {
+ // Array elem type
+ at := et.Elem()
+
// Special case of addressable (sliceable) array
- if mng := loadReflectKnownSlice(et); mng != nil {
- if count == 1 {
- return mng, nil
- }
- return nil, deref_ptr_mangler(mng, count-1)
+ if mng := loadReflectKnownSlice(at); mng != nil {
+ rmng := array_to_slice_mangler(mng)
+ return nil, deref_ptr_rmangler(rmng, count)
}
// Look for an array mangler function, this will
// access elements by index using reflect.Value and
// pass each one to a separate mangler function.
- if rmng := loadReflectArray(et); rmng != nil {
+ if rmng := loadReflectArray(at); rmng != nil {
return nil, deref_ptr_rmangler(rmng, count)
}
@@ -321,14 +312,14 @@ func loadReflectMap(kt, vt reflect.Type) rMangler {
mng, rmng = load(nil, vt)
switch {
- // Wrap key mangler to reflect
+ // Wrap value mangler to reflect
case mng != nil:
mng := mng // take our own ptr
vmng = func(buf []byte, v reflect.Value) []byte {
return mng(buf, v.Interface())
}
- // Use reflect key mangler as-is
+ // Use reflect value mangler as-is
case rmng != nil:
vmng = rmng
diff --git a/vendor/codeberg.org/gruf/go-mangler/mangle.go b/vendor/codeberg.org/gruf/go-mangler/mangle.go
index 983216003..e12748e67 100644
--- a/vendor/codeberg.org/gruf/go-mangler/mangle.go
+++ b/vendor/codeberg.org/gruf/go-mangler/mangle.go
@@ -1,19 +1,13 @@
package mangler
import (
- "encoding/binary"
"reflect"
"sync"
"unsafe"
)
-var (
- // manglers is a map of runtime type ptrs => Mangler functions.
- manglers = sync.Map{}
-
- // bin is a short-hand for our chosen byteorder encoding.
- bin = binary.LittleEndian
-)
+// manglers is a map of runtime type ptrs => Mangler functions.
+var manglers sync.Map
// Mangled is an interface that allows any type to implement a custom
// Mangler function to improve performance when mangling this type.
@@ -142,9 +136,15 @@ func Append(b []byte, a any) []byte {
// - float32,float64
// - complex64,complex128
// - all type aliases of above
-// - time.Time{}, *url.URL{}
+// - time.Time{}
+// - url.URL{}
+// - net.IPAddr{}
+// - netip.Addr{}, netip.AddrPort{}
// - mangler.Mangled{}
+// - fmt.Stringer{}
+// - json.Marshaler{}
// - encoding.BinaryMarshaler{}
+// - encoding.TextMarshaler{}
// - all pointers to the above
// - all slices / arrays of the above
// - all map keys / values of the above
diff --git a/vendor/codeberg.org/gruf/go-mangler/manglers.go b/vendor/codeberg.org/gruf/go-mangler/manglers.go
index 52f9f0082..b9ba81705 100644
--- a/vendor/codeberg.org/gruf/go-mangler/manglers.go
+++ b/vendor/codeberg.org/gruf/go-mangler/manglers.go
@@ -1,10 +1,7 @@
package mangler
import (
- "encoding"
- "fmt"
"math/bits"
- "time"
_ "unsafe"
)
@@ -87,13 +84,13 @@ func mangle_8bit_slice(buf []byte, a any) []byte {
}
func mangle_16bit(buf []byte, a any) []byte {
- return bin.AppendUint16(buf, *(*uint16)(iface_value(a)))
+ return append_uint16(buf, *(*uint16)(iface_value(a)))
}
func mangle_16bit_ptr(buf []byte, a any) []byte {
if ptr := (*uint16)(iface_value(a)); ptr != nil {
buf = append(buf, '1')
- return bin.AppendUint16(buf, *ptr)
+ return append_uint16(buf, *ptr)
}
buf = append(buf, '0')
return buf
@@ -101,19 +98,19 @@ func mangle_16bit_ptr(buf []byte, a any) []byte {
func mangle_16bit_slice(buf []byte, a any) []byte {
for _, u := range *(*[]uint16)(iface_value(a)) {
- buf = bin.AppendUint16(buf, u)
+ buf = append_uint16(buf, u)
}
return buf
}
func mangle_32bit(buf []byte, a any) []byte {
- return bin.AppendUint32(buf, *(*uint32)(iface_value(a)))
+ return append_uint32(buf, *(*uint32)(iface_value(a)))
}
func mangle_32bit_ptr(buf []byte, a any) []byte {
if ptr := (*uint32)(iface_value(a)); ptr != nil {
buf = append(buf, '1')
- return bin.AppendUint32(buf, *ptr)
+ return append_uint32(buf, *ptr)
}
buf = append(buf, '0')
return buf
@@ -121,19 +118,19 @@ func mangle_32bit_ptr(buf []byte, a any) []byte {
func mangle_32bit_slice(buf []byte, a any) []byte {
for _, u := range *(*[]uint32)(iface_value(a)) {
- buf = bin.AppendUint32(buf, u)
+ buf = append_uint32(buf, u)
}
return buf
}
func mangle_64bit(buf []byte, a any) []byte {
- return bin.AppendUint64(buf, *(*uint64)(iface_value(a)))
+ return append_uint64(buf, *(*uint64)(iface_value(a)))
}
func mangle_64bit_ptr(buf []byte, a any) []byte {
if ptr := (*uint64)(iface_value(a)); ptr != nil {
buf = append(buf, '1')
- return bin.AppendUint64(buf, *ptr)
+ return append_uint64(buf, *ptr)
}
buf = append(buf, '0')
return buf
@@ -141,7 +138,7 @@ func mangle_64bit_ptr(buf []byte, a any) []byte {
func mangle_64bit_slice(buf []byte, a any) []byte {
for _, u := range *(*[]uint64)(iface_value(a)) {
- buf = bin.AppendUint64(buf, u)
+ buf = append_uint64(buf, u)
}
return buf
}
@@ -187,16 +184,16 @@ type uint128 [2]uint64
func mangle_128bit(buf []byte, a any) []byte {
u2 := *(*uint128)(iface_value(a))
- buf = bin.AppendUint64(buf, u2[0])
- buf = bin.AppendUint64(buf, u2[1])
+ buf = append_uint64(buf, u2[0])
+ buf = append_uint64(buf, u2[1])
return buf
}
func mangle_128bit_ptr(buf []byte, a any) []byte {
if ptr := (*uint128)(iface_value(a)); ptr != nil {
buf = append(buf, '1')
- buf = bin.AppendUint64(buf, (*ptr)[0])
- buf = bin.AppendUint64(buf, (*ptr)[1])
+ buf = append_uint64(buf, (*ptr)[0])
+ buf = append_uint64(buf, (*ptr)[1])
}
buf = append(buf, '0')
return buf
@@ -204,26 +201,26 @@ func mangle_128bit_ptr(buf []byte, a any) []byte {
func mangle_128bit_slice(buf []byte, a any) []byte {
for _, u2 := range *(*[]uint128)(iface_value(a)) {
- buf = bin.AppendUint64(buf, u2[0])
- buf = bin.AppendUint64(buf, u2[1])
+ buf = append_uint64(buf, u2[0])
+ buf = append_uint64(buf, u2[1])
}
return buf
}
-func mangle_time(buf []byte, a any) []byte {
- t := *(*time.Time)(iface_value(a))
- b, err := t.MarshalBinary()
- if err != nil {
- panic("marshal_time: " + err.Error())
+func mangle_mangled(buf []byte, a any) []byte {
+ if v := a.(Mangled); v != nil {
+ buf = append(buf, '1')
+ return v.Mangle(buf)
}
- return append(buf, b...)
+ buf = append(buf, '0')
+ return buf
}
-func mangle_time_ptr(buf []byte, a any) []byte {
- if ptr := (*time.Time)(iface_value(a)); ptr != nil {
- b, err := ptr.MarshalBinary()
+func mangle_binary(buf []byte, a any) []byte {
+ if v := a.(binarymarshaler); v != nil {
+ b, err := v.MarshalBinary()
if err != nil {
- panic("marshal_time: " + err.Error())
+ panic("mangle_binary: " + err.Error())
}
buf = append(buf, '1')
return append(buf, b...)
@@ -232,20 +229,20 @@ func mangle_time_ptr(buf []byte, a any) []byte {
return buf
}
-func mangle_mangled(buf []byte, a any) []byte {
- if v := a.(Mangled); v != nil {
+func mangle_stringer(buf []byte, a any) []byte {
+ if v := a.(stringer); v != nil {
buf = append(buf, '1')
- return v.Mangle(buf)
+ return append(buf, v.String()...)
}
buf = append(buf, '0')
return buf
}
-func mangle_binary(buf []byte, a any) []byte {
- if v := a.(encoding.BinaryMarshaler); v != nil {
- b, err := v.MarshalBinary()
+func mangle_text(buf []byte, a any) []byte {
+ if v := a.(textmarshaler); v != nil {
+ b, err := v.MarshalText()
if err != nil {
- panic("mangle_binary: " + err.Error())
+ panic("mangle_text: " + err.Error())
}
buf = append(buf, '1')
return append(buf, b...)
@@ -254,10 +251,14 @@ func mangle_binary(buf []byte, a any) []byte {
return buf
}
-func mangle_stringer(buf []byte, a any) []byte {
- if v := a.(fmt.Stringer); v != nil {
+func mangle_json(buf []byte, a any) []byte {
+ if v := a.(jsonmarshaler); v != nil {
+ b, err := v.MarshalJSON()
+ if err != nil {
+ panic("mangle_json: " + err.Error())
+ }
buf = append(buf, '1')
- return append(buf, v.String()...)
+ return append(buf, b...)
}
buf = append(buf, '0')
return buf