github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/query/storage/m3/options.go (about)

     1  // Copyright (c) 2020  Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package m3
    22  
    23  import (
    24  	"context"
    25  	"errors"
    26  	"fmt"
    27  	"time"
    28  
    29  	"github.com/m3db/m3/src/dbnode/client"
    30  	"github.com/m3db/m3/src/dbnode/encoding"
    31  	"github.com/m3db/m3/src/query/models"
    32  	"github.com/m3db/m3/src/query/pools"
    33  	"github.com/m3db/m3/src/query/storage"
    34  	"github.com/m3db/m3/src/query/storage/m3/consolidators"
    35  	"github.com/m3db/m3/src/x/instrument"
    36  	"github.com/m3db/m3/src/x/pool"
    37  	xsync "github.com/m3db/m3/src/x/sync"
    38  )
    39  
    40  var (
    41  	defaultCapacity             = 1024
    42  	defaultCount                = 10
    43  	defaultLookbackDuration     = time.Duration(0)
    44  	defaultConsolidationFn      = consolidators.TakeLast
    45  	defaultIteratorBatchingFn   = iteratorBatchingFn
    46  	defaultBlockSeriesProcessor = NewBlockSeriesProcessor()
    47  	defaultInstrumented         = true
    48  	defaultTagsTransform        = func(ctx context.Context, ns ClusterNamespace, tags []models.Tag) (
    49  		[]models.Tag, error) {
    50  		return tags, nil
    51  	}
    52  	defaultRateLimiter = &noopRateLimiter{}
    53  )
    54  
    55  type dynamicClusterOptions struct {
    56  	config                   []DynamicClusterNamespaceConfiguration
    57  	iOpts                    instrument.Options
    58  	clusterNamespacesWatcher ClusterNamespacesWatcher
    59  }
    60  
    61  // NewDynamicClusterOptions returns new DynamicClusterOptions.
    62  func NewDynamicClusterOptions() DynamicClusterOptions {
    63  	return &dynamicClusterOptions{
    64  		iOpts: instrument.NewOptions(),
    65  	}
    66  }
    67  
    68  func (d *dynamicClusterOptions) Validate() error {
    69  	if len(d.config) == 0 {
    70  		return errDynamicClusterNamespaceConfigurationNotSet
    71  	}
    72  	if d.iOpts == nil {
    73  		return errInstrumentOptionsNotSet
    74  	}
    75  	if d.clusterNamespacesWatcher == nil {
    76  		return errClusterNamespacesWatcherNotSet
    77  	}
    78  
    79  	return nil
    80  }
    81  
    82  func (d *dynamicClusterOptions) SetDynamicClusterNamespaceConfiguration(
    83  	value []DynamicClusterNamespaceConfiguration,
    84  ) DynamicClusterOptions {
    85  	opts := *d
    86  	opts.config = value
    87  	return &opts
    88  }
    89  
    90  func (d *dynamicClusterOptions) DynamicClusterNamespaceConfiguration() []DynamicClusterNamespaceConfiguration {
    91  	return d.config
    92  }
    93  
    94  func (d *dynamicClusterOptions) SetInstrumentOptions(value instrument.Options) DynamicClusterOptions {
    95  	opts := *d
    96  	opts.iOpts = value
    97  	return &opts
    98  }
    99  
   100  func (d *dynamicClusterOptions) InstrumentOptions() instrument.Options {
   101  	return d.iOpts
   102  }
   103  
   104  func (d *dynamicClusterOptions) SetClusterNamespacesWatcher(value ClusterNamespacesWatcher) DynamicClusterOptions {
   105  	opts := *d
   106  	opts.clusterNamespacesWatcher = value
   107  	return &opts
   108  }
   109  
   110  func (d *dynamicClusterOptions) ClusterNamespacesWatcher() ClusterNamespacesWatcher {
   111  	return d.clusterNamespacesWatcher
   112  }
   113  
   114  // NewOptions creates a default encoded block options which dictates how
   115  // encoded blocks are generated.
   116  func NewOptions(encodingOpts encoding.Options) Options {
   117  	bytesPool := pool.NewCheckedBytesPool([]pool.Bucket{{
   118  		Capacity: defaultCapacity,
   119  		Count:    pool.Size(defaultCount),
   120  	}}, nil, func(s []pool.Bucket) pool.BytesPool {
   121  		return pool.NewBytesPool(s, nil)
   122  	})
   123  	bytesPool.Init()
   124  
   125  	iteratorPools := pools.BuildIteratorPools(encodingOpts, pools.BuildIteratorPoolsOptions{})
   126  	return newOptions(bytesPool, iteratorPools)
   127  }
   128  
   129  //nolint:maligned
   130  type encodedBlockOptions struct {
   131  	splitSeries                   bool
   132  	lookbackDuration              time.Duration
   133  	consolidationFn               consolidators.ConsolidationFunc
   134  	tagOptions                    models.TagOptions
   135  	tagsTransform                 TagsTransform
   136  	rateLimiter                   RateLimiter
   137  	pools                         encoding.IteratorPools
   138  	checkedPools                  pool.CheckedBytesPool
   139  	readWorkerPools               xsync.PooledWorkerPool
   140  	writeWorkerPools              xsync.PooledWorkerPool
   141  	queryConsolidatorMatchOptions consolidators.MatchOptions
   142  	seriesIteratorProcessor       SeriesIteratorProcessor
   143  	batchingFn                    IteratorBatchingFn
   144  	blockSeriesProcessor          BlockSeriesProcessor
   145  	adminOptions                  []client.CustomAdminOption
   146  	promConvertOptions            storage.PromConvertOptions
   147  	instrumented                  bool
   148  }
   149  
   150  func newOptions(
   151  	bytesPool pool.CheckedBytesPool,
   152  	iteratorPools encoding.IteratorPools,
   153  ) Options {
   154  	return &encodedBlockOptions{
   155  		lookbackDuration:     defaultLookbackDuration,
   156  		consolidationFn:      defaultConsolidationFn,
   157  		tagOptions:           models.NewTagOptions(),
   158  		pools:                iteratorPools,
   159  		checkedPools:         bytesPool,
   160  		batchingFn:           defaultIteratorBatchingFn,
   161  		blockSeriesProcessor: defaultBlockSeriesProcessor,
   162  		instrumented:         defaultInstrumented,
   163  		queryConsolidatorMatchOptions: consolidators.MatchOptions{
   164  			MatchType: consolidators.MatchIDs,
   165  		},
   166  		rateLimiter:        defaultRateLimiter,
   167  		tagsTransform:      defaultTagsTransform,
   168  		promConvertOptions: storage.NewPromConvertOptions(),
   169  	}
   170  }
   171  
   172  func (o *encodedBlockOptions) SetSplitSeriesByBlock(split bool) Options {
   173  	opts := *o
   174  	opts.splitSeries = split
   175  	return &opts
   176  }
   177  
   178  func (o *encodedBlockOptions) SplittingSeriesByBlock() bool {
   179  	return o.splitSeries
   180  }
   181  
   182  func (o *encodedBlockOptions) SetLookbackDuration(lookback time.Duration) Options {
   183  	opts := *o
   184  	opts.lookbackDuration = lookback
   185  	return &opts
   186  }
   187  
   188  func (o *encodedBlockOptions) LookbackDuration() time.Duration {
   189  	return o.lookbackDuration
   190  }
   191  
   192  func (o *encodedBlockOptions) SetConsolidationFunc(fn consolidators.ConsolidationFunc) Options {
   193  	opts := *o
   194  	opts.consolidationFn = fn
   195  	return &opts
   196  }
   197  
   198  func (o *encodedBlockOptions) ConsolidationFunc() consolidators.ConsolidationFunc {
   199  	return o.consolidationFn
   200  }
   201  
   202  func (o *encodedBlockOptions) SetTagOptions(tagOptions models.TagOptions) Options {
   203  	opts := *o
   204  	opts.tagOptions = tagOptions
   205  	return &opts
   206  }
   207  
   208  func (o *encodedBlockOptions) TagOptions() models.TagOptions {
   209  	return o.tagOptions
   210  }
   211  
   212  func (o *encodedBlockOptions) SetTagsTransform(value TagsTransform) Options {
   213  	opts := *o
   214  	opts.tagsTransform = value
   215  	return &opts
   216  }
   217  
   218  func (o *encodedBlockOptions) TagsTransform() TagsTransform {
   219  	return o.tagsTransform
   220  }
   221  
   222  func (o *encodedBlockOptions) SetRateLimiter(value RateLimiter) Options {
   223  	opts := *o
   224  	opts.rateLimiter = value
   225  	return &opts
   226  }
   227  
   228  func (o *encodedBlockOptions) RateLimiter() RateLimiter {
   229  	return o.rateLimiter
   230  }
   231  
   232  func (o *encodedBlockOptions) SetIteratorPools(p encoding.IteratorPools) Options {
   233  	opts := *o
   234  	opts.pools = p
   235  	return &opts
   236  }
   237  
   238  func (o *encodedBlockOptions) IteratorPools() encoding.IteratorPools {
   239  	return o.pools
   240  }
   241  
   242  func (o *encodedBlockOptions) SetCheckedBytesPool(p pool.CheckedBytesPool) Options {
   243  	opts := *o
   244  	opts.checkedPools = p
   245  	return &opts
   246  }
   247  
   248  func (o *encodedBlockOptions) CheckedBytesPool() pool.CheckedBytesPool {
   249  	return o.checkedPools
   250  }
   251  
   252  func (o *encodedBlockOptions) SetReadWorkerPool(p xsync.PooledWorkerPool) Options {
   253  	opts := *o
   254  	opts.readWorkerPools = p
   255  	return &opts
   256  }
   257  
   258  func (o *encodedBlockOptions) ReadWorkerPool() xsync.PooledWorkerPool {
   259  	return o.readWorkerPools
   260  }
   261  
   262  func (o *encodedBlockOptions) SetWriteWorkerPool(p xsync.PooledWorkerPool) Options {
   263  	opts := *o
   264  	opts.writeWorkerPools = p
   265  	return &opts
   266  }
   267  
   268  func (o *encodedBlockOptions) WriteWorkerPool() xsync.PooledWorkerPool {
   269  	return o.writeWorkerPools
   270  }
   271  
   272  func (o *encodedBlockOptions) SetSeriesConsolidationMatchOptions(
   273  	value consolidators.MatchOptions) Options {
   274  	opts := *o
   275  	opts.queryConsolidatorMatchOptions = value
   276  	return &opts
   277  }
   278  
   279  func (o *encodedBlockOptions) SeriesConsolidationMatchOptions() consolidators.MatchOptions {
   280  	return o.queryConsolidatorMatchOptions
   281  }
   282  
   283  func (o *encodedBlockOptions) SetSeriesIteratorProcessor(p SeriesIteratorProcessor) Options {
   284  	opts := *o
   285  	opts.seriesIteratorProcessor = p
   286  	return &opts
   287  }
   288  
   289  func (o *encodedBlockOptions) SeriesIteratorProcessor() SeriesIteratorProcessor {
   290  	return o.seriesIteratorProcessor
   291  }
   292  
   293  func (o *encodedBlockOptions) SetIteratorBatchingFn(fn IteratorBatchingFn) Options {
   294  	opts := *o
   295  	opts.batchingFn = fn
   296  	return &opts
   297  }
   298  
   299  func (o *encodedBlockOptions) IteratorBatchingFn() IteratorBatchingFn {
   300  	return o.batchingFn
   301  }
   302  
   303  func (o *encodedBlockOptions) SetBlockSeriesProcessor(fn BlockSeriesProcessor) Options {
   304  	opts := *o
   305  	opts.blockSeriesProcessor = fn
   306  	return &opts
   307  }
   308  
   309  func (o *encodedBlockOptions) BlockSeriesProcessor() BlockSeriesProcessor {
   310  	return o.blockSeriesProcessor
   311  }
   312  
   313  func (o *encodedBlockOptions) SetCustomAdminOptions(
   314  	val []client.CustomAdminOption) Options {
   315  	opts := *o
   316  	opts.adminOptions = val
   317  	return &opts
   318  }
   319  
   320  func (o *encodedBlockOptions) CustomAdminOptions() []client.CustomAdminOption {
   321  	return o.adminOptions
   322  }
   323  
   324  func (o *encodedBlockOptions) SetInstrumented(i bool) Options {
   325  	opts := *o
   326  	opts.instrumented = i
   327  	return &opts
   328  }
   329  
   330  func (o *encodedBlockOptions) Instrumented() bool {
   331  	return o.instrumented
   332  }
   333  
   334  func (o *encodedBlockOptions) SetPromConvertOptions(value storage.PromConvertOptions) Options {
   335  	opts := *o
   336  	opts.promConvertOptions = value
   337  	return &opts
   338  }
   339  
   340  func (o *encodedBlockOptions) PromConvertOptions() storage.PromConvertOptions {
   341  	return o.promConvertOptions
   342  }
   343  
   344  func (o *encodedBlockOptions) Validate() error {
   345  	if o.lookbackDuration < 0 {
   346  		return errors.New("unable to validate block options; negative lookback")
   347  	}
   348  
   349  	if err := o.tagOptions.Validate(); err != nil {
   350  		return fmt.Errorf("unable to validate tag options, err: %w", err)
   351  	}
   352  
   353  	return nil
   354  }