diff options
| author | 2025-03-12 20:33:35 +0000 | |
|---|---|---|
| committer | 2025-03-12 20:33:35 +0000 | |
| commit | f30bb549aae20281e169d0e7eaf7d70730955f02 (patch) | |
| tree | bfef2396b10ca2af4a96bcbc097f05a191be6bbb /vendor/codeberg.org/gruf/go-mangler/helpers.go | |
| parent | [docs] Update swagger docs command (#3897) (diff) | |
| download | gotosocial-f30bb549aae20281e169d0e7eaf7d70730955f02.tar.xz | |
update go-structr to v0.9.0 with new Timeline{} cache type (#3903)
Diffstat (limited to 'vendor/codeberg.org/gruf/go-mangler/helpers.go')
| -rw-r--r-- | vendor/codeberg.org/gruf/go-mangler/helpers.go | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/vendor/codeberg.org/gruf/go-mangler/helpers.go b/vendor/codeberg.org/gruf/go-mangler/helpers.go index 4e37e1344..f64663e62 100644 --- a/vendor/codeberg.org/gruf/go-mangler/helpers.go +++ b/vendor/codeberg.org/gruf/go-mangler/helpers.go @@ -1,3 +1,5 @@ +//go:build go1.19 || go1.20 || go1.21 || go1.22 || go1.23 + package mangler import ( @@ -35,8 +37,17 @@ func append_uint64(b []byte, u uint64) []byte { } type typecontext struct { - ntype reflect.Type - rtype reflect.Type + isptr bool + direct bool + ntype reflect.Type + rtype reflect.Type +} + +func (ctx *typecontext) set_nested(direct bool) { + ctx.direct = ctx.direct && direct && !ctx.isptr + ctx.ntype = ctx.rtype + ctx.rtype = nil + ctx.isptr = false } func deref_ptr_mangler(ctx typecontext, mangle Mangler, n uint) Mangler { @@ -44,16 +55,14 @@ func deref_ptr_mangler(ctx typecontext, mangle Mangler, n uint) Mangler { panic("bad input") } - // Non-nested value types, - // i.e. just direct ptrs to - // primitives require one - // less dereference to ptr. - if ctx.ntype == nil { + // If this is a direct value type, i.e. non-nested primitive, + // or part of a single-field struct / single element array + // then it can be treated as a direct ptr with 1 less deref. + if ctx.direct { n-- } return func(buf []byte, ptr unsafe.Pointer) []byte { - // Deref n number times. for i := n; i > 0; i-- { @@ -117,6 +126,15 @@ func iter_array_mangler(ctx typecontext, mangle Mangler) Mangler { // no. array elements. n := ctx.ntype.Len() + // Optimize + // easy cases. + switch n { + case 0: + return empty_mangler + case 1: + return mangle + } + // memory size of elem. esz := ctx.rtype.Size() @@ -139,19 +157,27 @@ func iter_array_mangler(ctx typecontext, mangle Mangler) Mangler { } func iter_struct_mangler(ctx typecontext, manglers []Mangler) Mangler { - if ctx.rtype == nil || len(manglers) != ctx.rtype.NumField() { + if ctx.rtype == nil || len(manglers) != ctx.ntype.NumField() { panic("bad input") } + // Optimized easy cases. + switch len(manglers) { + case 0: + return empty_mangler + case 1: + return manglers[0] + } + type field struct { mangle Mangler offset uintptr } // Bundle together the fields and manglers. - fields := make([]field, ctx.rtype.NumField()) + fields := make([]field, ctx.ntype.NumField()) for i := range fields { - rfield := ctx.rtype.FieldByIndex([]int{i}) + rfield := ctx.ntype.Field(i) fields[i].offset = rfield.Offset fields[i].mangle = manglers[i] if fields[i].mangle == nil { @@ -178,6 +204,10 @@ func iter_struct_mangler(ctx typecontext, manglers []Mangler) Mangler { } } +func empty_mangler(buf []byte, _ unsafe.Pointer) []byte { + return buf +} + // array_at returns ptr to index in array at ptr, given element size. func array_at(ptr unsafe.Pointer, esz uintptr, i int) unsafe.Pointer { return unsafe.Pointer(uintptr(ptr) + esz*uintptr(i)) |
