github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ts/memory_test.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package ts
    12  
    13  import (
    14  	"math"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/testutils"
    19  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    20  )
    21  
    22  func TestGetMaxTimespan(t *testing.T) {
    23  	defer leaktest.AfterTest(t)()
    24  
    25  	for _, tc := range []struct {
    26  		r                   Resolution
    27  		opts                QueryMemoryOptions
    28  		expectedTimespan    int64
    29  		expectedErrorString string
    30  	}{
    31  		// Simplest case: One series, room for exactly one hour of query (need two
    32  		// slabs of memory budget, as queried time span may stagger across two
    33  		// slabs)
    34  		{
    35  			Resolution10s,
    36  			QueryMemoryOptions{
    37  				BudgetBytes:             2 * (sizeOfTimeSeriesData + sizeOfSample*360),
    38  				EstimatedSources:        1,
    39  				InterpolationLimitNanos: 0,
    40  			},
    41  			(1 * time.Hour).Nanoseconds(),
    42  			"",
    43  		},
    44  		// Not enough room for to make query.
    45  		{
    46  			Resolution10s,
    47  			QueryMemoryOptions{
    48  				BudgetBytes:             sizeOfTimeSeriesData + sizeOfSample*360,
    49  				EstimatedSources:        1,
    50  				InterpolationLimitNanos: 0,
    51  			},
    52  			0,
    53  			"insufficient",
    54  		},
    55  		// Not enough room because of multiple sources.
    56  		{
    57  			Resolution10s,
    58  			QueryMemoryOptions{
    59  				BudgetBytes:             2 * (sizeOfTimeSeriesData + sizeOfSample*360),
    60  				EstimatedSources:        2,
    61  				InterpolationLimitNanos: 0,
    62  			},
    63  			0,
    64  			"insufficient",
    65  		},
    66  		// 6 sources, room for 1 hour.
    67  		{
    68  			Resolution10s,
    69  			QueryMemoryOptions{
    70  				BudgetBytes:             12 * (sizeOfTimeSeriesData + sizeOfSample*360),
    71  				EstimatedSources:        6,
    72  				InterpolationLimitNanos: 0,
    73  			},
    74  			(1 * time.Hour).Nanoseconds(),
    75  			"",
    76  		},
    77  		// 6 sources, room for 2 hours.
    78  		{
    79  			Resolution10s,
    80  			QueryMemoryOptions{
    81  				BudgetBytes:             18 * (sizeOfTimeSeriesData + sizeOfSample*360),
    82  				EstimatedSources:        6,
    83  				InterpolationLimitNanos: 0,
    84  			},
    85  			(2 * time.Hour).Nanoseconds(),
    86  			"",
    87  		},
    88  		// Not enough room due to interpolation buffer.
    89  		{
    90  			Resolution10s,
    91  			QueryMemoryOptions{
    92  				BudgetBytes:             12 * (sizeOfTimeSeriesData + sizeOfSample*360),
    93  				EstimatedSources:        6,
    94  				InterpolationLimitNanos: 1,
    95  			},
    96  			0,
    97  			"insufficient",
    98  		},
    99  		// Sufficient room even with interpolation buffer.
   100  		{
   101  			Resolution10s,
   102  			QueryMemoryOptions{
   103  				BudgetBytes:             18 * (sizeOfTimeSeriesData + sizeOfSample*360),
   104  				EstimatedSources:        6,
   105  				InterpolationLimitNanos: 1,
   106  			},
   107  			(1 * time.Hour).Nanoseconds(),
   108  			"",
   109  		},
   110  		// Insufficient room for interpolation buffer (due to straddling)
   111  		{
   112  			Resolution10s,
   113  			QueryMemoryOptions{
   114  				BudgetBytes:             18 * (sizeOfTimeSeriesData + sizeOfSample*360),
   115  				EstimatedSources:        6,
   116  				InterpolationLimitNanos: int64(float64(Resolution10s.SlabDuration()) * 0.75),
   117  			},
   118  			0,
   119  			"insufficient",
   120  		},
   121  		// Sufficient room even with interpolation buffer.
   122  		{
   123  			Resolution10s,
   124  			QueryMemoryOptions{
   125  				BudgetBytes:             24 * (sizeOfTimeSeriesData + sizeOfSample*360),
   126  				EstimatedSources:        6,
   127  				InterpolationLimitNanos: int64(float64(Resolution10s.SlabDuration()) * 0.75),
   128  			},
   129  			(1 * time.Hour).Nanoseconds(),
   130  			"",
   131  		},
   132  		// 1ns test resolution.
   133  		{
   134  			resolution1ns,
   135  			QueryMemoryOptions{
   136  				BudgetBytes:             3 * (sizeOfTimeSeriesData + sizeOfSample*10),
   137  				EstimatedSources:        1,
   138  				InterpolationLimitNanos: 1,
   139  			},
   140  			10,
   141  			"",
   142  		},
   143  		// Overflow.
   144  		{
   145  			Resolution10s,
   146  			QueryMemoryOptions{
   147  				BudgetBytes:             math.MaxInt64,
   148  				EstimatedSources:        1,
   149  				InterpolationLimitNanos: math.MaxInt64,
   150  			},
   151  			math.MaxInt64,
   152  			"",
   153  		},
   154  	} {
   155  		t.Run("", func(t *testing.T) {
   156  			mem := QueryMemoryContext{
   157  				QueryMemoryOptions: tc.opts,
   158  			}
   159  			actual, err := mem.GetMaxTimespan(tc.r)
   160  			if !testutils.IsError(err, tc.expectedErrorString) {
   161  				t.Fatalf("got error %s, wanted error matching %s", err, tc.expectedErrorString)
   162  			}
   163  			if tc.expectedErrorString == "" {
   164  				return
   165  			}
   166  			if a, e := actual, tc.expectedTimespan; a != e {
   167  				t.Fatalf("got max timespan %d, wanted %d", a, e)
   168  			}
   169  		})
   170  	}
   171  }