From 1df1dc8fb9cd546f3e50ed5b72a40957f251c82c Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 23 Jan 2025 18:38:34 +0100 Subject: [PATCH] Improve sizegen to handle more types (#17583) Signed-off-by: Dirkjan Bussink --- go/mysql/decimal/cached_size.go | 1 + go/tools/sizegen/sizegen.go | 124 +++++++- go/vt/schema/cached_size.go | 11 + go/vt/sqlparser/cached_size.go | 292 ++++++++++++++++++ go/vt/vtgate/evalengine/cached_size.go | 47 +++ go/vt/vtgate/vindexes/cached_size.go | 36 +++ .../tabletserver/rules/cached_size.go | 2 + 7 files changed, 506 insertions(+), 7 deletions(-) diff --git a/go/mysql/decimal/cached_size.go b/go/mysql/decimal/cached_size.go index e7258579f55..87f6c201b80 100644 --- a/go/mysql/decimal/cached_size.go +++ b/go/mysql/decimal/cached_size.go @@ -29,6 +29,7 @@ func (cached *Decimal) CachedSize(alloc bool) int64 { } // field value *math/big.Int if cached.value != nil { + size += hack.RuntimeAllocSize(int64(cap(cached.value.Bits())) * 4) size += hack.RuntimeAllocSize(int64(32)) } return size diff --git a/go/tools/sizegen/sizegen.go b/go/tools/sizegen/sizegen.go index 17b155ad3f4..cc733c8826d 100644 --- a/go/tools/sizegen/sizegen.go +++ b/go/tools/sizegen/sizegen.go @@ -107,6 +107,8 @@ func isPod(tt types.Type) bool { return false } return true + case *types.Alias: + return isPod(types.Unalias(tt)) default: return false } @@ -152,8 +154,37 @@ func (sizegen *sizegen) generateType(pkg *types.Package, file *codeFile, named * sizegen.generateTyp(tt) } }) + + case *types.Slice: + impl, flag := sizegen.sizeImplForSlice(named.Obj(), tt) + file.impls = append(file.impls, codeImpl{ + code: impl, + name: named.String(), + flags: flag, + }) + case *types.Map: + impl, flag := sizegen.sizeImplForMap(named.Obj(), tt) + file.impls = append(file.impls, codeImpl{ + code: impl, + name: named.String(), + flags: flag, + }) + case *types.Basic: + impl, flag := sizegen.sizeImplForBasic(named.Obj(), tt) + file.impls = append(file.impls, codeImpl{ + code: impl, + name: named.String(), + flags: flag, + }) + case *types.Signature: + impl, flag := sizegen.sizeImplForSignature(named.Obj(), tt) + file.impls = append(file.impls, codeImpl{ + code: impl, + name: named.String(), + flags: flag, + }) default: - // no-op + panic(fmt.Sprintf("unhandled type: %v (%T)", named, tt)) } } @@ -286,6 +317,77 @@ func (sizegen *sizegen) sizeImplForStruct(name *types.TypeName, st *types.Struct return f, funcFlags } +func (sizegen *sizegen) sizeImplForSlice(name *types.TypeName, st *types.Slice) (jen.Code, codeFlag) { + var stmt []jen.Code + var funcFlags codeFlag + stmt, funcFlags = sizegen.sizeStmtForArray(stmt, jen.Op("*").Add(jen.Id("cached")), st.Elem()) + + f := jen.Func() + f.Params(jen.Id("cached").Op("*").Id(name.Name())) + f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64() + f.BlockFunc(func(b *jen.Group) { + b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0))))) + b.Add(jen.Id("size").Op(":=").Lit(int64(0))) + b.Add(jen.If(jen.Id("alloc")).Block( + jen.Id("size").Op("+=").Lit(hack.RuntimeAllocSize(sizegen.sizes.Sizeof(st))), + )) + for _, s := range stmt { + b.Add(s) + } + b.Add(jen.Return(jen.Id("size"))) + }) + return f, funcFlags +} + +func (sizegen *sizegen) sizeImplForMap(name *types.TypeName, st *types.Map) (jen.Code, codeFlag) { + stmt := sizegen.sizeStmtForMap(jen.Op("*").Add(jen.Id("cached")), st) + + f := jen.Func() + f.Params(jen.Id("cached").Op("*").Id(name.Name())) + f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64() + f.BlockFunc(func(b *jen.Group) { + b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0))))) + b.Add(jen.Id("size").Op(":=").Lit(int64(0))) + b.Add(jen.If(jen.Id("alloc")).Block( + jen.Id("size").Op("+=").Lit(hack.RuntimeAllocSize(sizegen.sizes.Sizeof(st))), + )) + for _, s := range stmt { + b.Add(s) + } + b.Add(jen.Return(jen.Id("size"))) + }) + return f, 0 +} + +func (sizegen *sizegen) sizeImplForBasic(name *types.TypeName, st *types.Basic) (jen.Code, codeFlag) { + f := jen.Func() + f.Params(jen.Id("cached").Op("*").Id(name.Name())) + f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64() + f.BlockFunc(func(b *jen.Group) { + b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0))))) + b.Add(jen.Id("size").Op(":=").Lit(int64(0))) + b.Add(jen.If(jen.Id("alloc")).Block( + jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(st)))), + )) + if st.Info()&types.IsString != 0 { + b.Add(jen.Id("size").Op("+=").Do(mallocsize(jen.Int64().Call(jen.Len(jen.Op("*").Add(jen.Id("cached"))))))) + } + b.Add(jen.Return(jen.Id("size"))) + }) + return f, 0 +} + +func (sizegen *sizegen) sizeImplForSignature(name *types.TypeName, _ *types.Signature) (jen.Code, codeFlag) { + f := jen.Func() + f.Params(jen.Id("cached").Op("*").Id(name.Name())) + f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64() + f.BlockFunc(func(b *jen.Group) { + // assume that function pointers do not allocate (although they might, if they're closures) + b.Add(jen.Return(jen.Lit(int64(0)))) + }) + return f, 0 +} + func (sizegen *sizegen) sizeStmtForMap(fieldName *jen.Statement, m *types.Map) []jen.Code { const bucketCnt = 8 const sizeofHmap = int64(6 * 8) @@ -447,12 +549,21 @@ func (sizegen *sizegen) sizeStmtForType(fieldName *jen.Statement, field types.Ty ts := sizegen.getKnownType(node) if ts.pod || !ts.local { if alloc { - if !ts.local { - log.Printf("WARNING: size of external type %s cannot be fully calculated", node) + var stmts []jen.Code + if node.String() == "math/big.Int" { + // This type is not accessible, but with the given + // accessors we can compute a proper size. + stmts = append(stmts, jen.Id("size"). + Op("+="). + Do(mallocsize(jen.Int64().Call(jen.Cap(fieldName.Clone().Dot("Bits").Call())). + Op("*"). + Lit(4), + ))) + } else if !ts.local { + stmts = append(stmts, jen.Commentf("WARNING: size of external type %s cannot be fully calculated", node)) } - return jen.If(fieldName.Clone().Op("!=").Nil()).Block( - jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(node.Underlying())))), - ), 0 + stmts = append(stmts, jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(node.Underlying()))))) + return jen.If(fieldName.Clone().Op("!=").Nil()).Block(stmts...), 0 } return nil, 0 } @@ -502,7 +613,6 @@ func (sizegen *sizegen) sizeStmtForType(fieldName *jen.Statement, field types.Ty var defaultGenTypes = []string{ "vitess.io/vitess/go/pools/smartconnpool.Setting", - "vitess.io/vitess/go/vt/schema.DDLStrategySetting", "vitess.io/vitess/go/vt/vtgate/engine.Plan", "vitess.io/vitess/go/vt/vttablet/tabletserver.TabletPlan", "vitess.io/vitess/go/sqltypes.Result", diff --git a/go/vt/schema/cached_size.go b/go/vt/schema/cached_size.go index a2ea8f55deb..5ed67c01696 100644 --- a/go/vt/schema/cached_size.go +++ b/go/vt/schema/cached_size.go @@ -19,6 +19,17 @@ package schema import hack "vitess.io/vitess/go/hack" +func (cached *DDLStrategy) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += hack.RuntimeAllocSize(int64(16)) + } + size += hack.RuntimeAllocSize(int64(len(*cached))) + return size +} func (cached *DDLStrategySetting) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/sqlparser/cached_size.go b/go/vt/sqlparser/cached_size.go index 3aac4ac1edd..7183ff18e28 100644 --- a/go/vt/sqlparser/cached_size.go +++ b/go/vt/sqlparser/cached_size.go @@ -788,6 +788,20 @@ func (cached *ColumnTypeOptions) CachedSize(alloc bool) int64 { size += cached.SRID.CachedSize(true) return size } +func (cached *Columns) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(32)) + for _, elem := range *cached { + size += elem.CachedSize(false) + } + return size +} //go:nocheckptr func (cached *CommentDirectives) CachedSize(alloc bool) int64 { @@ -832,6 +846,20 @@ func (cached *CommentOnly) CachedSize(alloc bool) int64 { } return size } +func (cached *Comments) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + size += hack.RuntimeAllocSize(int64(len(elem))) + } + return size +} func (cached *CommonTableExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -1313,6 +1341,22 @@ func (cached *ExplainTab) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Wild))) return size } +func (cached *Exprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *ExtractFuncExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -1819,6 +1863,20 @@ func (cached *IndexHint) CachedSize(alloc bool) int64 { } return size } +func (cached *IndexHints) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *IndexInfo) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -2696,6 +2754,17 @@ func (cached *LinestrPropertyFuncExpr) CachedSize(alloc bool) int64 { } return size } +func (cached *ListArg) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += hack.RuntimeAllocSize(int64(16)) + } + size += hack.RuntimeAllocSize(int64(len(*cached))) + return size +} func (cached *Literal) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -2962,6 +3031,20 @@ func (cached *NamedWindow) CachedSize(alloc bool) int64 { } return size } +func (cached *NamedWindows) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *Nextval) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3020,6 +3103,20 @@ func (cached *Offset) CachedSize(alloc bool) int64 { } return size } +func (cached *OnDup) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *OptLike) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3064,6 +3161,20 @@ func (cached *Order) CachedSize(alloc bool) int64 { } return size } +func (cached *OrderBy) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *OrderByOption) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3297,6 +3408,20 @@ func (cached *PartitionValueRange) CachedSize(alloc bool) int64 { } return size } +func (cached *Partitions) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(32)) + for _, elem := range *cached { + size += elem.CachedSize(false) + } + return size +} func (cached *PerformanceSchemaFuncExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3753,6 +3878,22 @@ func (cached *Select) CachedSize(alloc bool) int64 { size += cached.Into.CachedSize(true) return size } +func (cached *SelectExprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *SelectInto) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3810,6 +3951,20 @@ func (cached *SetExpr) CachedSize(alloc bool) int64 { } return size } +func (cached *SetExprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *Show) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4095,6 +4250,20 @@ func (cached *SubPartitionDefinitionOptions) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.TableSpace))) return size } +func (cached *SubPartitionDefinitions) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *Subquery) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4161,6 +4330,36 @@ func (cached *TableAndLockType) CachedSize(alloc bool) int64 { } return size } +func (cached *TableAndLockTypes) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} +func (cached *TableExprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *TableName) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4175,6 +4374,20 @@ func (cached *TableName) CachedSize(alloc bool) int64 { size += cached.Qualifier.CachedSize(false) return size } +func (cached *TableNames) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(32)) + for _, elem := range *cached { + size += elem.CachedSize(false) + } + return size +} func (cached *TableOption) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4198,6 +4411,20 @@ func (cached *TableOption) CachedSize(alloc bool) int64 { } return size } +func (cached *TableOptions) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *TableSpec) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4398,6 +4625,20 @@ func (cached *UpdateExpr) CachedSize(alloc bool) int64 { } return size } +func (cached *UpdateExprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *UpdateXMLExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4470,6 +4711,22 @@ func (cached *VStream) CachedSize(alloc bool) int64 { size += cached.Limit.CachedSize(true) return size } +func (cached *ValTuple) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *Validation) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4480,6 +4737,27 @@ func (cached *Validation) CachedSize(alloc bool) int64 { } return size } +func (cached *Values) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(24)) + for _, elem := range *cached { + { + size += hack.RuntimeAllocSize(int64(cap(elem)) * int64(16)) + for _, elem := range elem { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + } + } + return size +} func (cached *ValuesFuncExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4688,6 +4966,20 @@ func (cached *WindowDefinition) CachedSize(alloc bool) int64 { size += cached.WindowSpec.CachedSize(true) return size } +func (cached *WindowDefinitions) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *WindowSpecification) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/vtgate/evalengine/cached_size.go b/go/vt/vtgate/evalengine/cached_size.go index d51c65c75b4..b953afda95c 100644 --- a/go/vt/vtgate/evalengine/cached_size.go +++ b/go/vt/vtgate/evalengine/cached_size.go @@ -175,6 +175,20 @@ func (cached *Column) CachedSize(alloc bool) int64 { } return size } +func (cached *Comparison) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(56)) + for _, elem := range *cached { + size += elem.CachedSize(false) + } + return size +} func (cached *ComparisonExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -245,6 +259,20 @@ func (cached *ConvertUsingExpr) CachedSize(alloc bool) int64 { size += cached.CollationEnv.CachedSize(true) return size } +func (cached *EnumSetValues) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + size += hack.RuntimeAllocSize(int64(len(elem))) + } + return size +} func (cached *InExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -391,6 +419,22 @@ func (cached *TupleBindVariable) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Key))) return size } +func (cached *TupleExpr) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *Type) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -2114,6 +2158,9 @@ func (cached *evalYear) CachedSize(alloc bool) int64 { } return size } +func (cached *frame) CachedSize(alloc bool) int64 { + return int64(0) +} func (cached *typedExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/vtgate/vindexes/cached_size.go b/go/vt/vtgate/vindexes/cached_size.go index eeadb69b532..ac68887c00d 100644 --- a/go/vt/vtgate/vindexes/cached_size.go +++ b/go/vt/vtgate/vindexes/cached_size.go @@ -392,6 +392,24 @@ func (cached *Numeric) CachedSize(alloc bool) int64 { } return size } +func (cached *NumericLookupTable) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(8) + } + size += int64(48) + hmap := reflect.ValueOf(*cached) + numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) + numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) + size += hack.RuntimeAllocSize(int64(numOldBuckets * 144)) + if len(*cached) > 0 || numBuckets > 1 { + size += hack.RuntimeAllocSize(int64(numBuckets * 144)) + } + return size +} //go:nocheckptr func (cached *NumericStaticMap) CachedSize(alloc bool) int64 { @@ -482,6 +500,24 @@ func (cached *RegionJSON) CachedSize(alloc bool) int64 { } return size } +func (cached *RegionMap) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(8) + } + size += int64(48) + hmap := reflect.ValueOf(*cached) + numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) + numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) + size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) + if len(*cached) > 0 || numBuckets > 1 { + size += hack.RuntimeAllocSize(int64(numBuckets * 208)) + } + return size +} func (cached *ReverseBits) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/vttablet/tabletserver/rules/cached_size.go b/go/vt/vttablet/tabletserver/rules/cached_size.go index 1375ef2cb7b..d06a31ab8cb 100644 --- a/go/vt/vttablet/tabletserver/rules/cached_size.go +++ b/go/vt/vttablet/tabletserver/rules/cached_size.go @@ -108,6 +108,7 @@ func (cached *bvcre) CachedSize(alloc bool) int64 { } // field re *regexp.Regexp if cached.re != nil { + // WARNING: size of external type regexp.Regexp cannot be fully calculated size += hack.RuntimeAllocSize(int64(160)) } return size @@ -124,6 +125,7 @@ func (cached *namedRegexp) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.name))) // field Regexp *regexp.Regexp if cached.Regexp != nil { + // WARNING: size of external type regexp.Regexp cannot be fully calculated size += hack.RuntimeAllocSize(int64(160)) } return size