github.com/grafana/pyroscope@v1.18.0/pkg/util/config.go (about)

     1  // SPDX-License-Identifier: AGPL-3.0-only
     2  // Provenance-includes-location: https://github.com/cortexproject/cortex/blob/master/pkg/util/config.go
     3  // Provenance-includes-license: Apache-2.0
     4  // Provenance-includes-copyright: The Cortex Authors.
     5  
     6  package util
     7  
     8  import (
     9  	"fmt"
    10  	"reflect"
    11  	"time"
    12  )
    13  
    14  func stringKeyMapToInterfaceKeyMap(m map[string]interface{}) map[interface{}]interface{} {
    15  	result := map[interface{}]interface{}{}
    16  	for k, v := range m {
    17  		result[k] = v
    18  	}
    19  	return result
    20  }
    21  
    22  // DiffConfig utility function that returns the diff between two config map objects
    23  func DiffConfig(defaultConfig, actualConfig map[interface{}]interface{}) (map[interface{}]interface{}, error) {
    24  	output := make(map[interface{}]interface{})
    25  
    26  	for key, value := range actualConfig {
    27  
    28  		defaultValue, ok := defaultConfig[key]
    29  		if !ok {
    30  			output[key] = value
    31  			continue
    32  		}
    33  
    34  		switch v := value.(type) {
    35  		case int:
    36  			defaultV, ok := defaultValue.(int)
    37  			if !ok || defaultV != v {
    38  				output[key] = v
    39  			}
    40  		case string:
    41  			defaultV, ok := defaultValue.(string)
    42  			if !ok || defaultV != v {
    43  				output[key] = v
    44  			}
    45  		case bool:
    46  			defaultV, ok := defaultValue.(bool)
    47  			if !ok || defaultV != v {
    48  				output[key] = v
    49  			}
    50  		case []interface{}:
    51  			defaultV, ok := defaultValue.([]interface{})
    52  			if !ok || !reflect.DeepEqual(defaultV, v) {
    53  				output[key] = v
    54  			}
    55  		case float64:
    56  			defaultV, ok := defaultValue.(float64)
    57  			if !ok || !reflect.DeepEqual(defaultV, v) {
    58  				output[key] = v
    59  			}
    60  		case nil:
    61  			if defaultValue != nil {
    62  				output[key] = v
    63  			}
    64  		case time.Time:
    65  			if defaultValue != nil && !v.IsZero() {
    66  				output[key] = v
    67  			}
    68  		case map[interface{}]interface{}:
    69  			defaultV, ok := defaultValue.(map[interface{}]interface{})
    70  			if !ok {
    71  				output[key] = value
    72  			}
    73  			diff, err := DiffConfig(defaultV, v)
    74  			if err != nil {
    75  				return nil, err
    76  			}
    77  			if len(diff) > 0 {
    78  				output[key] = diff
    79  			}
    80  		case map[string]interface{}:
    81  			defaultV, ok := defaultValue.(map[string]interface{})
    82  			if !ok {
    83  				output[key] = value
    84  			}
    85  			diff, err := DiffConfig(stringKeyMapToInterfaceKeyMap(defaultV), stringKeyMapToInterfaceKeyMap(v))
    86  			if err != nil {
    87  				return nil, err
    88  			}
    89  			if len(diff) > 0 {
    90  				output[key] = diff
    91  			}
    92  		default:
    93  			return nil, fmt.Errorf("unsupported type %T", v)
    94  		}
    95  	}
    96  
    97  	return output, nil
    98  }