github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/stmtsummary/variables.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package stmtsummary
    15  
    16  import (
    17  	"fmt"
    18  	"strconv"
    19  	"strings"
    20  	"sync"
    21  	"sync/atomic"
    22  
    23  	"github.com/whtcorpsinc/errors"
    24  	"github.com/whtcorpsinc/milevadb/config"
    25  )
    26  
    27  const (
    28  	typeEnable = iota
    29  	typeEnableInternalQuery
    30  	typeRefreshInterval
    31  	typeHistorySize
    32  	typeMaxStmtCount
    33  	typeMaxALLEGROSQLLength
    34  	typesNum
    35  )
    36  
    37  type systemVars struct {
    38  	sync.Mutex
    39  	// This array itself won't be modified once created. Only its elements may be modified.
    40  	variables []variable
    41  }
    42  
    43  type variable struct {
    44  	stochastikValue string
    45  	globalValue  string
    46  	finalValue   int64
    47  }
    48  
    49  func newSysVars() *systemVars {
    50  	s := &systemVars{
    51  		variables: make([]variable, typesNum),
    52  	}
    53  	// Initialize these configurations by values in the config file.
    54  	// They may be overwritten by system variables later.
    55  	for varType := range s.variables {
    56  		atomic.StoreInt64(&s.variables[varType].finalValue, getConfigValue(varType))
    57  	}
    58  	return s
    59  }
    60  
    61  func (s *systemVars) getVariable(varType int) int64 {
    62  	return atomic.LoadInt64(&s.variables[varType].finalValue)
    63  }
    64  
    65  func (s *systemVars) setVariable(varType int, valueStr string, isStochastik bool) error {
    66  	s.Lock()
    67  	defer s.Unlock()
    68  
    69  	v := &s.variables[varType]
    70  	if isStochastik {
    71  		v.stochastikValue = valueStr
    72  	} else {
    73  		v.globalValue = valueStr
    74  	}
    75  	stochastikValue := v.stochastikValue
    76  	globalValue := v.globalValue
    77  
    78  	var valueInt int64
    79  	switch varType {
    80  	case typeEnable, typeEnableInternalQuery:
    81  		valueInt = getBoolFinalVariable(varType, stochastikValue, globalValue)
    82  	case typeHistorySize, typeMaxALLEGROSQLLength:
    83  		valueInt = getIntFinalVariable(varType, stochastikValue, globalValue, 0)
    84  	case typeRefreshInterval, typeMaxStmtCount:
    85  		valueInt = getIntFinalVariable(varType, stochastikValue, globalValue, 1)
    86  	default:
    87  		return errors.New(fmt.Sprintf("no such type of variable: %d", varType))
    88  	}
    89  	atomic.StoreInt64(&v.finalValue, valueInt)
    90  	return nil
    91  }
    92  
    93  func getBoolFinalVariable(varType int, stochastikValue, globalValue string) int64 {
    94  	var valueInt int64
    95  	if len(stochastikValue) > 0 {
    96  		valueInt = normalizeEnableValue(stochastikValue)
    97  	} else if len(globalValue) > 0 {
    98  		valueInt = normalizeEnableValue(globalValue)
    99  	} else {
   100  		valueInt = getConfigValue(varType)
   101  	}
   102  	return valueInt
   103  }
   104  
   105  // normalizeEnableValue converts 'ON' or '1' to 1 and 'OFF' or '0' to 0.
   106  func normalizeEnableValue(value string) int64 {
   107  	switch {
   108  	case strings.EqualFold(value, "ON"):
   109  		return 1
   110  	case value == "1":
   111  		return 1
   112  	default:
   113  		return 0
   114  	}
   115  }
   116  
   117  func getIntFinalVariable(varType int, stochastikValue, globalValue string, minValue int64) int64 {
   118  	valueInt := minValue - 1
   119  	var err error
   120  	if len(stochastikValue) > 0 {
   121  		valueInt, err = strconv.ParseInt(stochastikValue, 10, 64)
   122  		if err != nil {
   123  			valueInt = minValue - 1
   124  		}
   125  	}
   126  	if valueInt < minValue {
   127  		valueInt, err = strconv.ParseInt(globalValue, 10, 64)
   128  		if err != nil {
   129  			valueInt = minValue - 1
   130  		}
   131  	}
   132  	// If stochastik and global variables are both '', use the value in config.
   133  	if valueInt < minValue {
   134  		valueInt = getConfigValue(varType)
   135  	}
   136  	return valueInt
   137  }
   138  
   139  func getConfigValue(varType int) int64 {
   140  	var valueInt int64
   141  	stmtSummaryConfig := config.GetGlobalConfig().StmtSummary
   142  	switch varType {
   143  	case typeEnable:
   144  		if stmtSummaryConfig.Enable {
   145  			valueInt = 1
   146  		}
   147  	case typeEnableInternalQuery:
   148  		if stmtSummaryConfig.EnableInternalQuery {
   149  			valueInt = 1
   150  		}
   151  	case typeRefreshInterval:
   152  		valueInt = int64(stmtSummaryConfig.RefreshInterval)
   153  	case typeHistorySize:
   154  		valueInt = int64(stmtSummaryConfig.HistorySize)
   155  	case typeMaxStmtCount:
   156  		valueInt = int64(stmtSummaryConfig.MaxStmtCount)
   157  	case typeMaxALLEGROSQLLength:
   158  		valueInt = int64(stmtSummaryConfig.MaxALLEGROSQLLength)
   159  	default:
   160  		panic(fmt.Sprintf("No such type of variable: %d", varType))
   161  	}
   162  	return valueInt
   163  }