mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-04 03:52:24 -06:00 
			
		
		
		
	[chore]: Bump github.com/gin-contrib/gzip from 1.0.1 to 1.1.0 (#3639)
Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.0.1 to 1.1.0. - [Release notes](https://github.com/gin-contrib/gzip/releases) - [Changelog](https://github.com/gin-contrib/gzip/blob/master/.goreleaser.yaml) - [Commits](https://github.com/gin-contrib/gzip/compare/v1.0.1...v1.1.0) --- updated-dependencies: - dependency-name: github.com/gin-contrib/gzip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
		
					parent
					
						
							
								8cfae010a9
							
						
					
				
			
			
				commit
				
					
						4d423102c1
					
				
			
		
					 519 changed files with 156968 additions and 132058 deletions
				
			
		
							
								
								
									
										0
									
								
								vendor/github.com/bytedance/sonic/internal/optcaching/asm.s
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								vendor/github.com/bytedance/sonic/internal/optcaching/asm.s
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										362
									
								
								vendor/github.com/bytedance/sonic/internal/optcaching/fcache.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										362
									
								
								vendor/github.com/bytedance/sonic/internal/optcaching/fcache.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,362 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2021 ByteDance Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package caching
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"github.com/bytedance/sonic/internal/envs"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/native"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/resolver"
 | 
			
		||||
	"github.com/bytedance/sonic/internal/rt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const _AlignSize =  32
 | 
			
		||||
const _PaddingSize =  32
 | 
			
		||||
 | 
			
		||||
type FieldLookup interface {
 | 
			
		||||
	Set(fields []resolver.FieldMeta)
 | 
			
		||||
	Get(name string) int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isAscii(s string) bool {
 | 
			
		||||
	for i :=0; i < len(s); i++ {
 | 
			
		||||
		if s[i] > unicode.MaxASCII {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewFieldLookup(fields []resolver.FieldMeta) FieldLookup {
 | 
			
		||||
	var f FieldLookup
 | 
			
		||||
	isAsc := true
 | 
			
		||||
	n := len(fields)
 | 
			
		||||
 | 
			
		||||
	// when field name has non-ascii, use the fallback methods to use strings.ToLower
 | 
			
		||||
	for _, f := range fields {
 | 
			
		||||
		if !isAscii(f.Name) {
 | 
			
		||||
			isAsc = false
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if n <= 8 {
 | 
			
		||||
		f =  NewSmallFieldMap(n)
 | 
			
		||||
	} else if envs.UseFastMap && n <= 128 && isAsc {
 | 
			
		||||
		f =   NewNormalFieldMap(n)
 | 
			
		||||
	} else {
 | 
			
		||||
		f =   NewFallbackFieldMap(n)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	f.Set(fields)
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Map for keys nums max 8, idx is in [0, 8)
 | 
			
		||||
type SmallFieldMap struct {
 | 
			
		||||
	keys []string
 | 
			
		||||
	lowerKeys []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewSmallFieldMap (hint int) *SmallFieldMap {
 | 
			
		||||
	return &SmallFieldMap{
 | 
			
		||||
		keys: make([]string, hint, hint),
 | 
			
		||||
		lowerKeys: make([]string, hint, hint),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *SmallFieldMap) Set(fields []resolver.FieldMeta) {
 | 
			
		||||
	if len(fields) > 8 {
 | 
			
		||||
		panic("small field map shoud use in small struct")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, f := range fields {
 | 
			
		||||
		self.keys[i] = f.Name
 | 
			
		||||
		self.lowerKeys[i] = strings.ToLower(f.Name)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *SmallFieldMap) Get(name string) int {
 | 
			
		||||
	for i, k := range self.keys {
 | 
			
		||||
		if len(k) == len(name) && k == name {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	name = strings.ToLower(name)
 | 
			
		||||
	for i, k := range self.lowerKeys {
 | 
			
		||||
		if len(k) == len(name) && k == name {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
1. select by the length: 0 ~ 32 and larger lengths
 | 
			
		||||
2. simd match the aligned prefix of the keys: 4/8/16/32 bytes or larger keys
 | 
			
		||||
3. check the key with strict match
 | 
			
		||||
4. check the key with case-insensitive match
 | 
			
		||||
5. find the index 
 | 
			
		||||
 | 
			
		||||
Mem Layout:
 | 
			
		||||
     fixed 33 * 5 bytes  165 bytes |||  variable keys  ||| variable lowerkeys
 | 
			
		||||
| length metadata array[33] ||| key0.0 | u8 | key0.1 | u8 | ...  || key1.0 | u8 | key1.1 | u8 | ...  ||| lowerkeys info ...
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Map for keys nums max 255, idx is in [0, 255), idx 255 means not found.
 | 
			
		||||
// keysoffset
 | 
			
		||||
// | metadata | aligned key0 | aligned key1 | ... |
 | 
			
		||||
// 1 ~ 8
 | 
			
		||||
// 8 ~ 16
 | 
			
		||||
// 16 ~ 32
 | 
			
		||||
// > 32 keys use the long keys entry lists
 | 
			
		||||
// use bytes to reduce GC
 | 
			
		||||
type NormalFieldMap struct {
 | 
			
		||||
	keys  			[]byte
 | 
			
		||||
	longKeys		[]keyEntry
 | 
			
		||||
	// offset for lower
 | 
			
		||||
	lowOffset	    int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type keyEntry struct {
 | 
			
		||||
	key 		string
 | 
			
		||||
	lowerKey	string
 | 
			
		||||
	index		uint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewNormalFieldMap(n int) *NormalFieldMap {
 | 
			
		||||
	return &NormalFieldMap{
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _HdrSlot = 33
 | 
			
		||||
const _HdrSize = _HdrSlot * 5
 | 
			
		||||
 | 
			
		||||
// use native SIMD to accelerate it
 | 
			
		||||
func (self *NormalFieldMap) Get(name string) int {
 | 
			
		||||
	// small keys use native C
 | 
			
		||||
	if len(name) <= 32 {
 | 
			
		||||
		 _ = native.LookupSmallKey
 | 
			
		||||
		return native.LookupSmallKey(&name, &self.keys, self.lowOffset);
 | 
			
		||||
	}
 | 
			
		||||
	return self.getLongKey(name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *NormalFieldMap) getLongKey(name string) int {
 | 
			
		||||
	for _, k := range self.longKeys {
 | 
			
		||||
		if len(k.key) != len(name) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if k.key == name {
 | 
			
		||||
			return int(k.index)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lower := strings.ToLower(name)
 | 
			
		||||
	for _, k := range self.longKeys {
 | 
			
		||||
		if len(k.key) != len(name) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if k.lowerKey == lower {
 | 
			
		||||
			return int(k.index)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *NormalFieldMap) Getdouble(name string) int {
 | 
			
		||||
	if len(name) > 32 {
 | 
			
		||||
		for _, k := range self.longKeys {
 | 
			
		||||
			if len(k.key) != len(name) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if k.key == name {
 | 
			
		||||
				return int(k.index)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return self.getCaseInsensitive(name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check the fixed length keys, not found the target length
 | 
			
		||||
	cnt := int(self.keys[5 * len(name)])
 | 
			
		||||
	if cnt == 0 {
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	p := ((*rt.GoSlice)(unsafe.Pointer(&self.keys))).Ptr
 | 
			
		||||
	offset := int(*(*int32)(unsafe.Pointer(uintptr(p) + uintptr(5 * len(name) + 1)))) + _HdrSize
 | 
			
		||||
	for i := 0; i < cnt; i++ {
 | 
			
		||||
		key := rt.Mem2Str(self.keys[offset: offset + len(name)])
 | 
			
		||||
		if key == name {
 | 
			
		||||
			return int(self.keys[offset + len(name)])
 | 
			
		||||
		}
 | 
			
		||||
		offset += len(name) + 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return self.getCaseInsensitive(name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *NormalFieldMap) getCaseInsensitive(name string) int {
 | 
			
		||||
	lower := strings.ToLower(name)
 | 
			
		||||
	if len(name) > 32 {
 | 
			
		||||
		for _, k := range self.longKeys {
 | 
			
		||||
			if len(k.key) != len(name) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if k.lowerKey == lower {
 | 
			
		||||
				return int(k.index)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cnt := int(self.keys[5 * len(name)])
 | 
			
		||||
	p := ((*rt.GoSlice)(unsafe.Pointer(&self.keys))).Ptr
 | 
			
		||||
	offset := int(*(*int32)(unsafe.Pointer(uintptr(p) + uintptr(5 * len(name) + 1)))) + self.lowOffset
 | 
			
		||||
	for i := 0; i < cnt; i++ {
 | 
			
		||||
		key := rt.Mem2Str(self.keys[offset: offset + len(name)])
 | 
			
		||||
		if key == lower {
 | 
			
		||||
			return int(self.keys[offset + len(name)])
 | 
			
		||||
		}
 | 
			
		||||
		offset += len(name) + 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type keysInfo struct {
 | 
			
		||||
	counts int
 | 
			
		||||
	lenSum int
 | 
			
		||||
	offset int
 | 
			
		||||
	cur    int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *NormalFieldMap) Set(fields []resolver.FieldMeta) {
 | 
			
		||||
	if len(fields) <=8 || len(fields) > 128 {
 | 
			
		||||
		panic("normal field map shoud use in small struct")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// allocate the flat map in []byte
 | 
			
		||||
	var keyLenSum [_HdrSlot]keysInfo
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < _HdrSlot; i++ {
 | 
			
		||||
		keyLenSum[i].offset = 0
 | 
			
		||||
		keyLenSum[i].counts = 0
 | 
			
		||||
		keyLenSum[i].lenSum = 0
 | 
			
		||||
		keyLenSum[i].cur = 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kvLen := 0
 | 
			
		||||
	for _, f := range(fields) {
 | 
			
		||||
		len := len(f.Name)
 | 
			
		||||
		if len <= 32 {
 | 
			
		||||
			kvLen += len + 1 // key + index
 | 
			
		||||
			keyLenSum[len].counts++
 | 
			
		||||
			keyLenSum[len].lenSum += len + 1
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// add a padding size at last to make it firendly for SIMD.
 | 
			
		||||
	self.keys = make([]byte, _HdrSize + 2 * kvLen, _HdrSize + 2 * kvLen + _PaddingSize)
 | 
			
		||||
	self.lowOffset = _HdrSize + kvLen
 | 
			
		||||
 | 
			
		||||
	// initialize all keys offset
 | 
			
		||||
	self.keys[0] = byte(keyLenSum[0].counts)
 | 
			
		||||
	// self.keys[1:5] = 0 // offset is always zero here.
 | 
			
		||||
	i := 1
 | 
			
		||||
	p := ((*rt.GoSlice)(unsafe.Pointer(&self.keys))).Ptr
 | 
			
		||||
	for i < _HdrSlot {
 | 
			
		||||
		keyLenSum[i].offset = keyLenSum[i-1].offset + keyLenSum[i-1].lenSum
 | 
			
		||||
		self.keys[i * 5] = byte(keyLenSum[i].counts)
 | 
			
		||||
		// write the offset into []byte
 | 
			
		||||
		*(*int32)(unsafe.Pointer(uintptr(p) + uintptr(i * 5 + 1))) = int32(keyLenSum[i].offset)
 | 
			
		||||
		i += 1
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// fill the key into bytes
 | 
			
		||||
	for i, f := range(fields) {
 | 
			
		||||
		len := len(f.Name)
 | 
			
		||||
		if len <= 32 {
 | 
			
		||||
			offset := keyLenSum[len].offset +  keyLenSum[len].cur
 | 
			
		||||
			copy(self.keys[_HdrSize + offset: ], f.Name)
 | 
			
		||||
			copy(self.keys[self.lowOffset + offset: ], strings.ToLower(f.Name))
 | 
			
		||||
			self.keys[_HdrSize + offset + len] = byte(i)
 | 
			
		||||
			self.keys[self.lowOffset + offset + len] = byte(i)
 | 
			
		||||
			keyLenSum[len].cur += len + 1
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
			self.longKeys = append(self.longKeys, keyEntry{f.Name, strings.ToLower(f.Name), uint(i)})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// use hashnap
 | 
			
		||||
type FallbackFieldMap struct {
 | 
			
		||||
	oders  []string
 | 
			
		||||
	inner  map[string]int
 | 
			
		||||
	backup map[string]int
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
 func NewFallbackFieldMap(n int) *FallbackFieldMap {
 | 
			
		||||
	 return &FallbackFieldMap{
 | 
			
		||||
		 oders:  make([]string, n, n),
 | 
			
		||||
		 inner:  make(map[string]int, n*2),
 | 
			
		||||
		 backup: make(map[string]int, n*2),
 | 
			
		||||
	 }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 func (self *FallbackFieldMap) Get(name string) int {
 | 
			
		||||
	 if i, ok := self.inner[name]; ok {
 | 
			
		||||
		 return i
 | 
			
		||||
	 } else {
 | 
			
		||||
		 return self.getCaseInsensitive(name)
 | 
			
		||||
	 }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 func (self *FallbackFieldMap) Set(fields []resolver.FieldMeta) {
 | 
			
		||||
 | 
			
		||||
	for i, f := range(fields) {
 | 
			
		||||
		name := f.Name
 | 
			
		||||
		self.oders[i] = name
 | 
			
		||||
		self.inner[name] = i
 | 
			
		||||
	
 | 
			
		||||
		/* add the case-insensitive version, prefer the one with smaller field ID */
 | 
			
		||||
		key := strings.ToLower(name)
 | 
			
		||||
		if v, ok := self.backup[key]; !ok || i < v {
 | 
			
		||||
			self.backup[key] = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 func (self *FallbackFieldMap) getCaseInsensitive(name string) int {
 | 
			
		||||
	 if i, ok := self.backup[strings.ToLower(name)]; ok {
 | 
			
		||||
		 return i
 | 
			
		||||
	 } else {
 | 
			
		||||
		 return -1
 | 
			
		||||
	 }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue