summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/DmitriyVTitov/size/.gitignore19
-rw-r--r--vendor/github.com/DmitriyVTitov/size/LICENSE21
-rw-r--r--vendor/github.com/DmitriyVTitov/size/README.md48
-rw-r--r--vendor/github.com/DmitriyVTitov/size/size.go142
4 files changed, 230 insertions, 0 deletions
diff --git a/vendor/github.com/DmitriyVTitov/size/.gitignore b/vendor/github.com/DmitriyVTitov/size/.gitignore
new file mode 100644
index 000000000..ae4c566d2
--- /dev/null
+++ b/vendor/github.com/DmitriyVTitov/size/.gitignore
@@ -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 \ No newline at end of file
diff --git a/vendor/github.com/DmitriyVTitov/size/LICENSE b/vendor/github.com/DmitriyVTitov/size/LICENSE
new file mode 100644
index 000000000..507b0b74c
--- /dev/null
+++ b/vendor/github.com/DmitriyVTitov/size/LICENSE
@@ -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.
diff --git a/vendor/github.com/DmitriyVTitov/size/README.md b/vendor/github.com/DmitriyVTitov/size/README.md
new file mode 100644
index 000000000..215a749cc
--- /dev/null
+++ b/vendor/github.com/DmitriyVTitov/size/README.md
@@ -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
+```
diff --git a/vendor/github.com/DmitriyVTitov/size/size.go b/vendor/github.com/DmitriyVTitov/size/size.go
new file mode 100644
index 000000000..b52e2c41d
--- /dev/null
+++ b/vendor/github.com/DmitriyVTitov/size/size.go
@@ -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
+}