From 1fd484fe806026ca3452c90bbcecb8e6c9ce1249 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Thu, 30 Jun 2022 17:05:39 +0800 Subject: [PATCH 1/4] done Signed-off-by: wjhuang2016 --- types/json/path_expr.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/types/json/path_expr.go b/types/json/path_expr.go index 5d23c1a16ed3a..cee5f56c33c4b 100644 --- a/types/json/path_expr.go +++ b/types/json/path_expr.go @@ -15,11 +15,15 @@ package json import ( + "math" "regexp" "strconv" "strings" + "sync" "github.com/pingcap/errors" + "github.com/pingcap/tidb/util/hack" + "github.com/pingcap/tidb/util/kvcache" ) /* @@ -92,6 +96,20 @@ type PathExpression struct { flags pathExpressionFlag } +var peCache PathExpressionCache + +type pathExpressionKey string + +func (key pathExpressionKey) Hash() []byte { + return hack.Slice(string(key)) +} + +// PathExpressionCache is a cache for PathExpression. +type PathExpressionCache struct { + mu sync.Mutex + cache *kvcache.SimpleLRUCache +} + // popOneLeg returns a pathLeg, and a child PathExpression without that leg. func (pe PathExpression) popOneLeg() (pathLeg, PathExpression) { newPe := PathExpression{ @@ -150,6 +168,22 @@ func (pe PathExpression) ContainsAnyAsterisk() bool { // ParseJSONPathExpr parses a JSON path expression. Returns a PathExpression // object which can be used in JSON_EXTRACT, JSON_SET and so on. func ParseJSONPathExpr(pathExpr string) (pe PathExpression, err error) { + peCache.mu.Lock() + val, ok := peCache.cache.Get(pathExpressionKey(pathExpr)) + if ok { + peCache.mu.Unlock() + return val.(PathExpression), nil + } + peCache.mu.Unlock() + + defer func() { + if err == nil { + peCache.mu.Lock() + peCache.cache.Put(pathExpressionKey(pathExpr), kvcache.Value(pe)) + peCache.mu.Unlock() + } + }() + // Find the position of first '$'. If any no-blank characters in // pathExpr[0: dollarIndex), return an ErrInvalidJSONPath error. dollarIndex := strings.Index(pathExpr, "$") @@ -261,3 +295,7 @@ func (pe PathExpression) String() string { } return s.String() } + +func init() { + peCache.cache = kvcache.NewSimpleLRUCache(1000, 0.1, math.MaxUint64) +} From 5d6715cdcc257b428d4671e18eded5d99255a14e Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Thu, 30 Jun 2022 17:31:59 +0800 Subject: [PATCH 2/4] fix cycle_reference Signed-off-by: wjhuang2016 --- config/const.go | 3 --- util/memory/tracker.go | 6 ++++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/config/const.go b/config/const.go index 42c314cd64cef..9196e1b9929d8 100644 --- a/config/const.go +++ b/config/const.go @@ -16,6 +16,3 @@ package config // DefRowsForSampleRate is default sample rows used to calculate samplerate. const DefRowsForSampleRate = 110000 - -// TrackMemWhenExceeds is the threshold when memory usage needs to be tracked. -const TrackMemWhenExceeds = 104857600 // 100MB diff --git a/util/memory/tracker.go b/util/memory/tracker.go index 106ff210e83ed..42eb9f61a6e06 100644 --- a/util/memory/tracker.go +++ b/util/memory/tracker.go @@ -22,11 +22,13 @@ import ( "sync" "sync/atomic" - "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/metrics" atomicutil "go.uber.org/atomic" ) +// TrackMemWhenExceeds is the threshold when memory usage needs to be tracked. +const TrackMemWhenExceeds = 104857600 // 100MB + // Tracker is used to track the memory usage during query execution. // It contains an optional limit and can be arranged into a tree structure // such that the consumption tracked by a Tracker is also tracked by @@ -388,7 +390,7 @@ func (t *Tracker) Consume(bytes int64) { // BufferedConsume is used to buffer memory usage and do late consume func (t *Tracker) BufferedConsume(bufferedMemSize *int64, bytes int64) { *bufferedMemSize += bytes - if *bufferedMemSize > int64(config.TrackMemWhenExceeds) { + if *bufferedMemSize > int64(TrackMemWhenExceeds) { t.Consume(*bufferedMemSize) *bufferedMemSize = int64(0) } From 9113c4b807d8c2e5ef8f6cb7f33cb46039990b23 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Thu, 30 Jun 2022 17:35:06 +0800 Subject: [PATCH 3/4] set capability to 10M Signed-off-by: wjhuang2016 --- types/json/path_expr.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/types/json/path_expr.go b/types/json/path_expr.go index cee5f56c33c4b..320c929a6e58b 100644 --- a/types/json/path_expr.go +++ b/types/json/path_expr.go @@ -15,7 +15,6 @@ package json import ( - "math" "regexp" "strconv" "strings" @@ -297,5 +296,5 @@ func (pe PathExpression) String() string { } func init() { - peCache.cache = kvcache.NewSimpleLRUCache(1000, 0.1, math.MaxUint64) + peCache.cache = kvcache.NewSimpleLRUCache(1000, 0.1, 10485760 /* 10M */) } From f8b8f273705dc532404549dbbb36171915af2f9b Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Thu, 30 Jun 2022 17:53:04 +0800 Subject: [PATCH 4/4] Revert "set capability to 10M" This reverts commit 9113c4b807d8c2e5ef8f6cb7f33cb46039990b23. --- types/json/path_expr.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/types/json/path_expr.go b/types/json/path_expr.go index 320c929a6e58b..cee5f56c33c4b 100644 --- a/types/json/path_expr.go +++ b/types/json/path_expr.go @@ -15,6 +15,7 @@ package json import ( + "math" "regexp" "strconv" "strings" @@ -296,5 +297,5 @@ func (pe PathExpression) String() string { } func init() { - peCache.cache = kvcache.NewSimpleLRUCache(1000, 0.1, 10485760 /* 10M */) + peCache.cache = kvcache.NewSimpleLRUCache(1000, 0.1, math.MaxUint64) }