index_mapping.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Unless explicitly stated otherwise all files in this repository are licensed
  2. // under the Apache License 2.0.
  3. // This product includes software developed at Datadog (https://www.datadoghq.com/).
  4. // Copyright 2021 Datadog, Inc.
  5. package mapping
  6. import (
  7. "errors"
  8. "fmt"
  9. enc "github.com/DataDog/sketches-go/ddsketch/encoding"
  10. "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb"
  11. )
  12. const (
  13. expOverflow = 7.094361393031e+02 // The value at which math.Exp overflows
  14. minNormalFloat64 = 2.2250738585072014e-308 //2^(-1022)
  15. )
  16. type IndexMapping interface {
  17. Equals(other IndexMapping) bool
  18. Index(value float64) int
  19. Value(index int) float64
  20. LowerBound(index int) float64
  21. RelativeAccuracy() float64
  22. MinIndexableValue() float64
  23. MaxIndexableValue() float64
  24. ToProto() *sketchpb.IndexMapping
  25. // Encode encodes a mapping and appends its content to the provided []byte.
  26. Encode(b *[]byte)
  27. }
  28. func NewDefaultMapping(relativeAccuracy float64) (IndexMapping, error) {
  29. return NewLogarithmicMapping(relativeAccuracy)
  30. }
  31. // FromProto returns an Index mapping from the protobuf definition of it
  32. func FromProto(m *sketchpb.IndexMapping) (IndexMapping, error) {
  33. switch m.Interpolation {
  34. case sketchpb.IndexMapping_NONE:
  35. return NewLogarithmicMappingWithGamma(m.Gamma, m.IndexOffset)
  36. case sketchpb.IndexMapping_LINEAR:
  37. return NewLinearlyInterpolatedMappingWithGamma(m.Gamma, m.IndexOffset)
  38. case sketchpb.IndexMapping_CUBIC:
  39. return NewCubicallyInterpolatedMappingWithGamma(m.Gamma, m.IndexOffset)
  40. default:
  41. return nil, fmt.Errorf("interpolation not supported: %d", m.Interpolation)
  42. }
  43. }
  44. // Decode decodes a mapping and updates the provided []byte so that it starts
  45. // immediately after the encoded mapping.
  46. func Decode(b *[]byte, flag enc.Flag) (IndexMapping, error) {
  47. switch flag {
  48. case enc.FlagIndexMappingBaseLogarithmic:
  49. gamma, indexOffset, err := decodeLogLikeIndexMapping(b)
  50. if err != nil {
  51. return nil, err
  52. }
  53. return NewLogarithmicMappingWithGamma(gamma, indexOffset)
  54. case enc.FlagIndexMappingBaseLinear:
  55. gamma, indexOffset, err := decodeLogLikeIndexMapping(b)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return NewLinearlyInterpolatedMappingWithGamma(gamma, indexOffset)
  60. case enc.FlagIndexMappingBaseCubic:
  61. gamma, indexOffset, err := decodeLogLikeIndexMapping(b)
  62. if err != nil {
  63. return nil, err
  64. }
  65. return NewCubicallyInterpolatedMappingWithGamma(gamma, indexOffset)
  66. default:
  67. return nil, errors.New("unknown mapping")
  68. }
  69. }
  70. func decodeLogLikeIndexMapping(b *[]byte) (gamma, indexOffset float64, err error) {
  71. gamma, err = enc.DecodeFloat64LE(b)
  72. if err != nil {
  73. return
  74. }
  75. indexOffset, err = enc.DecodeFloat64LE(b)
  76. return
  77. }