mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] simpler cache size configuration (#2051)
* add automatic cache max size generation based on ratios of a singular fixed memory target Signed-off-by: kim <grufwub@gmail.com> * remove now-unused cache max-size config variables Signed-off-by: kim <grufwub@gmail.com> * slight ratio tweak Signed-off-by: kim <grufwub@gmail.com> * remove unused visibility config var Signed-off-by: kim <grufwub@gmail.com> * add secret little ratio config trick Signed-off-by: kim <grufwub@gmail.com> * fixed a word Signed-off-by: kim <grufwub@gmail.com> * update cache library to remove use of TTL in result caches + slice cache Signed-off-by: kim <grufwub@gmail.com> * update other cache usages to use correct interface Signed-off-by: kim <grufwub@gmail.com> * update example config to explain the cache memory target Signed-off-by: kim <grufwub@gmail.com> * update env parsing test with new config values Signed-off-by: kim <grufwub@gmail.com> * do some ratio twiddling Signed-off-by: kim <grufwub@gmail.com> * add missing header * update envparsing with latest defaults Signed-off-by: kim <grufwub@gmail.com> * update size calculations to take into account result cache, simple cache and extra map overheads Signed-off-by: kim <grufwub@gmail.com> * tweak the ratios some more Signed-off-by: kim <grufwub@gmail.com> * more nan rampaging Signed-off-by: kim <grufwub@gmail.com> * fix envparsing script Signed-off-by: kim <grufwub@gmail.com> * update cache library, add sweep function to keep caches trim Signed-off-by: kim <grufwub@gmail.com> * sweep caches once a minute Signed-off-by: kim <grufwub@gmail.com> * add a regular job to sweep caches and keep under 80% utilisation Signed-off-by: kim <grufwub@gmail.com> * remove dead code Signed-off-by: kim <grufwub@gmail.com> * add new size library used to libraries section of readme Signed-off-by: kim <grufwub@gmail.com> * add better explanations for the mem-ratio numbers Signed-off-by: kim <grufwub@gmail.com> * update go-cache Signed-off-by: kim <grufwub@gmail.com> * library version bump Signed-off-by: kim <grufwub@gmail.com> * update cache.result{} size model estimation Signed-off-by: kim <grufwub@gmail.com> --------- Signed-off-by: kim <grufwub@gmail.com>
This commit is contained in:
19
vendor/github.com/DmitriyVTitov/size/.gitignore
generated
vendored
Normal file
19
vendor/github.com/DmitriyVTitov/size/.gitignore
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
example
|
||||
.idea
|
||||
go.sum
|
21
vendor/github.com/DmitriyVTitov/size/LICENSE
generated
vendored
Normal file
21
vendor/github.com/DmitriyVTitov/size/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Dmitriy Titov (Дмитрий Титов)
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
48
vendor/github.com/DmitriyVTitov/size/README.md
generated
vendored
Normal file
48
vendor/github.com/DmitriyVTitov/size/README.md
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# size - calculates variable's memory consumption at runtime
|
||||
|
||||
### Part of the [Transflow Project](http://transflow.ru/)
|
||||
|
||||
Sometimes you may need a tool to measure the size of object in your Go program at runtime. This package makes an attempt to do so. Package based on `binary.Size()` from Go standard library.
|
||||
|
||||
Features:
|
||||
- supports non-fixed size variables and struct fields: `struct`, `int`, `slice`, `string`, `map`;
|
||||
- supports complex types including structs with non-fixed size fields;
|
||||
- supports all basic types (numbers, bool);
|
||||
- supports `chan` and `interface`;
|
||||
- supports pointers;
|
||||
- implements infinite recursion detection (i.e. pointer inside struct field references to parent struct).
|
||||
|
||||
### Usage example
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
// Use latest tag.
|
||||
"github.com/DmitriyVTitov/size"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := struct {
|
||||
a int
|
||||
b string
|
||||
c bool
|
||||
d int32
|
||||
e []byte
|
||||
f [3]int64
|
||||
}{
|
||||
a: 10, // 8 bytes
|
||||
b: "Text", // 16 (string itself) + 4 = 20 bytes
|
||||
c: true, // 1 byte
|
||||
d: 25, // 4 bytes
|
||||
e: []byte{'c', 'd', 'e'}, // 24 (slice itself) + 3 = 27 bytes
|
||||
f: [3]int64{1, 2, 3}, // 3 * 8 = 24 bytes
|
||||
} // 84 + 3 (padding) = 87 bytes
|
||||
|
||||
fmt.Println(size.Of(a))
|
||||
}
|
||||
|
||||
// Output: 87
|
||||
```
|
142
vendor/github.com/DmitriyVTitov/size/size.go
generated
vendored
Normal file
142
vendor/github.com/DmitriyVTitov/size/size.go
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
// Package size implements run-time calculation of size of the variable.
|
||||
// Source code is based on "binary.Size()" function from Go standard library.
|
||||
// size.Of() omits size of slices, arrays and maps containers itself (24, 24 and 8 bytes).
|
||||
// When counting maps separate calculations are done for keys and values.
|
||||
package size
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Of returns the size of 'v' in bytes.
|
||||
// If there is an error during calculation, Of returns -1.
|
||||
func Of(v interface{}) int {
|
||||
// Cache with every visited pointer so we don't count two pointers
|
||||
// to the same memory twice.
|
||||
cache := make(map[uintptr]bool)
|
||||
return sizeOf(reflect.Indirect(reflect.ValueOf(v)), cache)
|
||||
}
|
||||
|
||||
// sizeOf returns the number of bytes the actual data represented by v occupies in memory.
|
||||
// If there is an error, sizeOf returns -1.
|
||||
func sizeOf(v reflect.Value, cache map[uintptr]bool) int {
|
||||
switch v.Kind() {
|
||||
|
||||
case reflect.Array:
|
||||
sum := 0
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
s := sizeOf(v.Index(i), cache)
|
||||
if s < 0 {
|
||||
return -1
|
||||
}
|
||||
sum += s
|
||||
}
|
||||
|
||||
return sum + (v.Cap()-v.Len())*int(v.Type().Elem().Size())
|
||||
|
||||
case reflect.Slice:
|
||||
// return 0 if this node has been visited already
|
||||
if cache[v.Pointer()] {
|
||||
return 0
|
||||
}
|
||||
cache[v.Pointer()] = true
|
||||
|
||||
sum := 0
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
s := sizeOf(v.Index(i), cache)
|
||||
if s < 0 {
|
||||
return -1
|
||||
}
|
||||
sum += s
|
||||
}
|
||||
|
||||
sum += (v.Cap() - v.Len()) * int(v.Type().Elem().Size())
|
||||
|
||||
return sum + int(v.Type().Size())
|
||||
|
||||
case reflect.Struct:
|
||||
sum := 0
|
||||
for i, n := 0, v.NumField(); i < n; i++ {
|
||||
s := sizeOf(v.Field(i), cache)
|
||||
if s < 0 {
|
||||
return -1
|
||||
}
|
||||
sum += s
|
||||
}
|
||||
|
||||
// Look for struct padding.
|
||||
padding := int(v.Type().Size())
|
||||
for i, n := 0, v.NumField(); i < n; i++ {
|
||||
padding -= int(v.Field(i).Type().Size())
|
||||
}
|
||||
|
||||
return sum + padding
|
||||
|
||||
case reflect.String:
|
||||
s := v.String()
|
||||
hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
||||
if cache[hdr.Data] {
|
||||
return int(v.Type().Size())
|
||||
}
|
||||
cache[hdr.Data] = true
|
||||
return len(s) + int(v.Type().Size())
|
||||
|
||||
case reflect.Ptr:
|
||||
// return Ptr size if this node has been visited already (infinite recursion)
|
||||
if cache[v.Pointer()] {
|
||||
return int(v.Type().Size())
|
||||
}
|
||||
cache[v.Pointer()] = true
|
||||
if v.IsNil() {
|
||||
return int(reflect.New(v.Type()).Type().Size())
|
||||
}
|
||||
s := sizeOf(reflect.Indirect(v), cache)
|
||||
if s < 0 {
|
||||
return -1
|
||||
}
|
||||
return s + int(v.Type().Size())
|
||||
|
||||
case reflect.Bool,
|
||||
reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||
reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Int, reflect.Uint,
|
||||
reflect.Chan,
|
||||
reflect.Uintptr,
|
||||
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128,
|
||||
reflect.Func:
|
||||
return int(v.Type().Size())
|
||||
|
||||
case reflect.Map:
|
||||
// return 0 if this node has been visited already (infinite recursion)
|
||||
if cache[v.Pointer()] {
|
||||
return 0
|
||||
}
|
||||
cache[v.Pointer()] = true
|
||||
sum := 0
|
||||
keys := v.MapKeys()
|
||||
for i := range keys {
|
||||
val := v.MapIndex(keys[i])
|
||||
// calculate size of key and value separately
|
||||
sv := sizeOf(val, cache)
|
||||
if sv < 0 {
|
||||
return -1
|
||||
}
|
||||
sum += sv
|
||||
sk := sizeOf(keys[i], cache)
|
||||
if sk < 0 {
|
||||
return -1
|
||||
}
|
||||
sum += sk
|
||||
}
|
||||
// Include overhead due to unused map buckets. 10.79 comes
|
||||
// from https://golang.org/src/runtime/map.go.
|
||||
return sum + int(v.Type().Size()) + int(float64(len(keys))*10.79)
|
||||
|
||||
case reflect.Interface:
|
||||
return sizeOf(v.Elem(), cache) + int(v.Type().Size())
|
||||
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
Reference in New Issue
Block a user