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

     1  // Copyright (c) 2018 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 index
    22  
    23  import (
    24  	"errors"
    25  
    26  	"github.com/m3db/m3/src/dbnode/storage/index/compaction"
    27  	"github.com/m3db/m3/src/dbnode/storage/limits"
    28  	"github.com/m3db/m3/src/m3ninx/doc"
    29  	"github.com/m3db/m3/src/m3ninx/index/segment/builder"
    30  	"github.com/m3db/m3/src/m3ninx/index/segment/fst"
    31  	"github.com/m3db/m3/src/m3ninx/index/segment/mem"
    32  	"github.com/m3db/m3/src/x/clock"
    33  	"github.com/m3db/m3/src/x/ident"
    34  	"github.com/m3db/m3/src/x/instrument"
    35  	"github.com/m3db/m3/src/x/mmap"
    36  	"github.com/m3db/m3/src/x/pool"
    37  )
    38  
    39  const (
    40  	// defaultIndexInsertMode sets the default indexing mode to synchronous.
    41  	defaultIndexInsertMode = InsertSync
    42  
    43  	// metadataArrayPool size in general: 256*256*sizeof(doc.Metadata)
    44  	// = 256 * 256 * 48
    45  	// =~ 3mb
    46  	// TODO(r): Make this configurable in a followup change.
    47  	metadataArrayPoolSize = 256
    48  	// MetadataArrayPoolCapacity is the capacity of the metadata array pool.
    49  	MetadataArrayPoolCapacity    = 256
    50  	metadataArrayPoolMaxCapacity = 256 // Do not allow grows, since we know the size
    51  
    52  	// documentArrayPool size in general: 256*256*sizeof(doc.Document)
    53  	// = 256 * 256 * 80
    54  	// =~ 5mb
    55  	documentArrayPoolSize = 256
    56  	// DocumentArrayPoolCapacity is the capacity of the encoded document array pool.
    57  	DocumentArrayPoolCapacity    = 256
    58  	documentArrayPoolMaxCapacity = 256 // Do not allow grows, since we know the size
    59  
    60  	// aggregateResultsEntryArrayPool size in general: 256*256*sizeof(doc.Field)
    61  	// = 256 * 256 * 48
    62  	// =~ 3mb
    63  	// TODO(prateek): Make this configurable in a followup change.
    64  	aggregateResultsEntryArrayPoolSize        = 256
    65  	aggregateResultsEntryArrayPoolCapacity    = 256
    66  	aggregateResultsEntryArrayPoolMaxCapacity = 256 // Do not allow grows, since we know the size
    67  )
    68  
    69  var (
    70  	errOptionsIdentifierPoolUnspecified      = errors.New("identifier pool is unset")
    71  	errOptionsBytesPoolUnspecified           = errors.New("checkedbytes pool is unset")
    72  	errOptionsResultsPoolUnspecified         = errors.New("results pool is unset")
    73  	errOptionsAggResultsPoolUnspecified      = errors.New("aggregate results pool is unset")
    74  	errOptionsAggValuesPoolUnspecified       = errors.New("aggregate values pool is unset")
    75  	errOptionsDocPoolUnspecified             = errors.New("docs array pool is unset")
    76  	errOptionsDocContainerPoolUnspecified    = errors.New("doc container array pool is unset")
    77  	errOptionsAggResultsEntryPoolUnspecified = errors.New("aggregate results entry array pool is unset")
    78  	errIDGenerationDisabled                  = errors.New("id generation is disabled")
    79  	errPostingsListCacheUnspecified          = errors.New("postings list cache is unset")
    80  
    81  	defaultForegroundCompactionOpts compaction.PlannerOptions
    82  	defaultBackgroundCompactionOpts compaction.PlannerOptions
    83  )
    84  
    85  func init() {
    86  	// Foreground compaction opts are the same as background compaction
    87  	// but with only a single level, 1/4 the size of the first level of
    88  	// the background compaction.
    89  	defaultForegroundCompactionOpts = compaction.DefaultOptions
    90  	defaultForegroundCompactionOpts.Levels = []compaction.Level{
    91  		{
    92  			MinSizeInclusive: 0,
    93  			MaxSizeExclusive: 1 << 12,
    94  		},
    95  	}
    96  	defaultBackgroundCompactionOpts = compaction.DefaultOptions
    97  	defaultBackgroundCompactionOpts.Levels = []compaction.Level{
    98  		{
    99  			MinSizeInclusive: 0,
   100  			MaxSizeExclusive: 1 << 18,
   101  		},
   102  		{
   103  			MinSizeInclusive: 1 << 18,
   104  			MaxSizeExclusive: 1 << 20,
   105  		},
   106  		{
   107  			MinSizeInclusive: 1 << 20,
   108  			MaxSizeExclusive: 1 << 22,
   109  		},
   110  	}
   111  }
   112  
   113  // nolint: maligned
   114  type options struct {
   115  	forwardIndexThreshold           float64
   116  	forwardIndexProbability         float64
   117  	insertMode                      InsertMode
   118  	clockOpts                       clock.Options
   119  	instrumentOpts                  instrument.Options
   120  	builderOpts                     builder.Options
   121  	memOpts                         mem.Options
   122  	fstOpts                         fst.Options
   123  	idPool                          ident.Pool
   124  	bytesPool                       pool.CheckedBytesPool
   125  	resultsPool                     QueryResultsPool
   126  	aggResultsPool                  AggregateResultsPool
   127  	aggValuesPool                   AggregateValuesPool
   128  	docArrayPool                    doc.DocumentArrayPool
   129  	metadataArrayPool               doc.MetadataArrayPool
   130  	aggResultsEntryArrayPool        AggregateResultsEntryArrayPool
   131  	foregroundCompactionPlannerOpts compaction.PlannerOptions
   132  	backgroundCompactionPlannerOpts compaction.PlannerOptions
   133  	postingsListCache               *PostingsListCache
   134  	searchPostingsListCache         *PostingsListCache
   135  	readThroughSegmentOptions       ReadThroughSegmentOptions
   136  	mmapReporter                    mmap.Reporter
   137  	queryLimits                     limits.QueryLimits
   138  }
   139  
   140  var undefinedUUIDFn = func() ([]byte, error) { return nil, errIDGenerationDisabled }
   141  
   142  // NewOptions returns a new Options object with default properties.
   143  func NewOptions() Options {
   144  	resultsPool := NewQueryResultsPool(pool.NewObjectPoolOptions())
   145  	aggResultsPool := NewAggregateResultsPool(pool.NewObjectPoolOptions())
   146  	aggValuesPool := NewAggregateValuesPool(pool.NewObjectPoolOptions())
   147  
   148  	bytesPool := pool.NewCheckedBytesPool(nil, nil, func(s []pool.Bucket) pool.BytesPool {
   149  		return pool.NewBytesPool(s, nil)
   150  	})
   151  	bytesPool.Init()
   152  
   153  	idPool := ident.NewPool(bytesPool, ident.PoolOptions{})
   154  
   155  	docArrayPool := doc.NewDocumentArrayPool(doc.DocumentArrayPoolOpts{
   156  		Options: pool.NewObjectPoolOptions().
   157  			SetSize(documentArrayPoolSize),
   158  		Capacity:    DocumentArrayPoolCapacity,
   159  		MaxCapacity: documentArrayPoolMaxCapacity,
   160  	})
   161  	docArrayPool.Init()
   162  
   163  	metadataArrayPool := doc.NewMetadataArrayPool(doc.MetadataArrayPoolOpts{
   164  		Options: pool.NewObjectPoolOptions().
   165  			SetSize(metadataArrayPoolSize),
   166  		Capacity:    MetadataArrayPoolCapacity,
   167  		MaxCapacity: metadataArrayPoolMaxCapacity,
   168  	})
   169  	metadataArrayPool.Init()
   170  
   171  	aggResultsEntryArrayPool := NewAggregateResultsEntryArrayPool(AggregateResultsEntryArrayPoolOpts{
   172  		Options: pool.NewObjectPoolOptions().
   173  			SetSize(aggregateResultsEntryArrayPoolSize),
   174  		Capacity:    aggregateResultsEntryArrayPoolCapacity,
   175  		MaxCapacity: aggregateResultsEntryArrayPoolMaxCapacity,
   176  	})
   177  	aggResultsEntryArrayPool.Init()
   178  
   179  	instrumentOpts := instrument.NewOptions()
   180  	opts := &options{
   181  		insertMode:                      defaultIndexInsertMode,
   182  		clockOpts:                       clock.NewOptions(),
   183  		instrumentOpts:                  instrumentOpts,
   184  		builderOpts:                     builder.NewOptions().SetNewUUIDFn(undefinedUUIDFn),
   185  		memOpts:                         mem.NewOptions().SetNewUUIDFn(undefinedUUIDFn),
   186  		fstOpts:                         fst.NewOptions().SetInstrumentOptions(instrumentOpts),
   187  		bytesPool:                       bytesPool,
   188  		idPool:                          idPool,
   189  		resultsPool:                     resultsPool,
   190  		aggResultsPool:                  aggResultsPool,
   191  		aggValuesPool:                   aggValuesPool,
   192  		docArrayPool:                    docArrayPool,
   193  		metadataArrayPool:               metadataArrayPool,
   194  		aggResultsEntryArrayPool:        aggResultsEntryArrayPool,
   195  		foregroundCompactionPlannerOpts: defaultForegroundCompactionOpts,
   196  		backgroundCompactionPlannerOpts: defaultBackgroundCompactionOpts,
   197  		queryLimits:                     limits.NoOpQueryLimits(),
   198  	}
   199  	resultsPool.Init(func() QueryResults {
   200  		return NewQueryResults(nil, QueryResultsOptions{}, opts)
   201  	})
   202  	aggResultsPool.Init(func() AggregateResults {
   203  		return NewAggregateResults(nil, AggregateResultsOptions{}, opts)
   204  	})
   205  	aggValuesPool.Init(func() AggregateValues { return NewAggregateValues(opts) })
   206  	return opts
   207  }
   208  
   209  func (o *options) Validate() error {
   210  	if o.idPool == nil {
   211  		return errOptionsIdentifierPoolUnspecified
   212  	}
   213  	if o.bytesPool == nil {
   214  		return errOptionsBytesPoolUnspecified
   215  	}
   216  	if o.resultsPool == nil {
   217  		return errOptionsResultsPoolUnspecified
   218  	}
   219  	if o.aggResultsPool == nil {
   220  		return errOptionsAggResultsPoolUnspecified
   221  	}
   222  	if o.aggValuesPool == nil {
   223  		return errOptionsAggValuesPoolUnspecified
   224  	}
   225  	if o.docArrayPool == nil {
   226  		return errOptionsDocPoolUnspecified
   227  	}
   228  	if o.metadataArrayPool == nil {
   229  		return errOptionsDocContainerPoolUnspecified
   230  	}
   231  	if o.aggResultsEntryArrayPool == nil {
   232  		return errOptionsAggResultsEntryPoolUnspecified
   233  	}
   234  	if o.postingsListCache == nil {
   235  		return errPostingsListCacheUnspecified
   236  	}
   237  	return nil
   238  }
   239  
   240  func (o *options) SetInsertMode(value InsertMode) Options {
   241  	opts := *o
   242  	opts.insertMode = value
   243  	return &opts
   244  }
   245  
   246  func (o *options) InsertMode() InsertMode {
   247  	return o.insertMode
   248  }
   249  
   250  func (o *options) SetClockOptions(value clock.Options) Options {
   251  	opts := *o
   252  	opts.clockOpts = value
   253  	return &opts
   254  }
   255  
   256  func (o *options) ClockOptions() clock.Options {
   257  	return o.clockOpts
   258  }
   259  
   260  func (o *options) SetInstrumentOptions(value instrument.Options) Options {
   261  	opts := *o
   262  	memOpts := opts.MemSegmentOptions().SetInstrumentOptions(value)
   263  	fstOpts := opts.FSTSegmentOptions().SetInstrumentOptions(value)
   264  	opts.instrumentOpts = value
   265  	opts.memOpts = memOpts
   266  	opts.fstOpts = fstOpts
   267  	return &opts
   268  }
   269  
   270  func (o *options) InstrumentOptions() instrument.Options {
   271  	return o.instrumentOpts
   272  }
   273  
   274  func (o *options) SetSegmentBuilderOptions(value builder.Options) Options {
   275  	opts := *o
   276  	opts.builderOpts = value
   277  	return &opts
   278  }
   279  
   280  func (o *options) SegmentBuilderOptions() builder.Options {
   281  	return o.builderOpts
   282  }
   283  
   284  func (o *options) SetMemSegmentOptions(value mem.Options) Options {
   285  	opts := *o
   286  	opts.memOpts = value
   287  	return &opts
   288  }
   289  
   290  func (o *options) MemSegmentOptions() mem.Options {
   291  	return o.memOpts
   292  }
   293  
   294  func (o *options) SetFSTSegmentOptions(value fst.Options) Options {
   295  	opts := *o
   296  	opts.fstOpts = value
   297  	return &opts
   298  }
   299  
   300  func (o *options) FSTSegmentOptions() fst.Options {
   301  	return o.fstOpts
   302  }
   303  
   304  func (o *options) SetIdentifierPool(value ident.Pool) Options {
   305  	opts := *o
   306  	opts.idPool = value
   307  	return &opts
   308  }
   309  
   310  func (o *options) IdentifierPool() ident.Pool {
   311  	return o.idPool
   312  }
   313  
   314  func (o *options) SetCheckedBytesPool(value pool.CheckedBytesPool) Options {
   315  	opts := *o
   316  	opts.bytesPool = value
   317  	return &opts
   318  }
   319  
   320  func (o *options) CheckedBytesPool() pool.CheckedBytesPool {
   321  	return o.bytesPool
   322  }
   323  
   324  func (o *options) SetQueryResultsPool(value QueryResultsPool) Options {
   325  	opts := *o
   326  	opts.resultsPool = value
   327  	return &opts
   328  }
   329  
   330  func (o *options) QueryResultsPool() QueryResultsPool {
   331  	return o.resultsPool
   332  }
   333  
   334  func (o *options) SetAggregateResultsPool(value AggregateResultsPool) Options {
   335  	opts := *o
   336  	opts.aggResultsPool = value
   337  	return &opts
   338  }
   339  
   340  func (o *options) AggregateResultsPool() AggregateResultsPool {
   341  	return o.aggResultsPool
   342  }
   343  
   344  func (o *options) SetAggregateValuesPool(value AggregateValuesPool) Options {
   345  	opts := *o
   346  	opts.aggValuesPool = value
   347  	return &opts
   348  }
   349  
   350  func (o *options) AggregateValuesPool() AggregateValuesPool {
   351  	return o.aggValuesPool
   352  }
   353  
   354  func (o *options) SetDocumentArrayPool(value doc.DocumentArrayPool) Options {
   355  	opts := *o
   356  	opts.docArrayPool = value
   357  	return &opts
   358  }
   359  
   360  func (o *options) DocumentArrayPool() doc.DocumentArrayPool {
   361  	return o.docArrayPool
   362  }
   363  
   364  func (o *options) SetMetadataArrayPool(value doc.MetadataArrayPool) Options {
   365  	opts := *o // nolint:govet
   366  	opts.metadataArrayPool = value
   367  	return &opts
   368  }
   369  
   370  func (o *options) MetadataArrayPool() doc.MetadataArrayPool {
   371  	return o.metadataArrayPool
   372  }
   373  
   374  func (o *options) SetAggregateResultsEntryArrayPool(value AggregateResultsEntryArrayPool) Options {
   375  	opts := *o
   376  	opts.aggResultsEntryArrayPool = value
   377  	return &opts
   378  }
   379  
   380  func (o *options) AggregateResultsEntryArrayPool() AggregateResultsEntryArrayPool {
   381  	return o.aggResultsEntryArrayPool
   382  }
   383  
   384  func (o *options) SetForegroundCompactionPlannerOptions(value compaction.PlannerOptions) Options {
   385  	opts := *o
   386  	opts.foregroundCompactionPlannerOpts = value
   387  	return &opts
   388  }
   389  
   390  func (o *options) ForegroundCompactionPlannerOptions() compaction.PlannerOptions {
   391  	return o.foregroundCompactionPlannerOpts
   392  }
   393  
   394  func (o *options) SetBackgroundCompactionPlannerOptions(value compaction.PlannerOptions) Options {
   395  	opts := *o
   396  	opts.backgroundCompactionPlannerOpts = value
   397  	return &opts
   398  }
   399  
   400  func (o *options) BackgroundCompactionPlannerOptions() compaction.PlannerOptions {
   401  	return o.backgroundCompactionPlannerOpts
   402  }
   403  
   404  func (o *options) SetPostingsListCache(value *PostingsListCache) Options {
   405  	opts := *o
   406  	opts.postingsListCache = value
   407  	return &opts
   408  }
   409  
   410  func (o *options) PostingsListCache() *PostingsListCache {
   411  	return o.postingsListCache
   412  }
   413  
   414  func (o *options) SetSearchPostingsListCache(value *PostingsListCache) Options {
   415  	opts := *o
   416  	opts.searchPostingsListCache = value
   417  	return &opts
   418  }
   419  
   420  func (o *options) SearchPostingsListCache() *PostingsListCache {
   421  	return o.searchPostingsListCache
   422  }
   423  
   424  func (o *options) SetReadThroughSegmentOptions(value ReadThroughSegmentOptions) Options {
   425  	opts := *o
   426  	opts.readThroughSegmentOptions = value
   427  	return &opts
   428  }
   429  
   430  func (o *options) ReadThroughSegmentOptions() ReadThroughSegmentOptions {
   431  	return o.readThroughSegmentOptions
   432  }
   433  
   434  func (o *options) SetForwardIndexProbability(value float64) Options {
   435  	opts := *o
   436  	opts.forwardIndexProbability = value
   437  	return &opts
   438  }
   439  
   440  func (o *options) ForwardIndexProbability() float64 {
   441  	return o.forwardIndexProbability
   442  }
   443  
   444  func (o *options) SetForwardIndexThreshold(value float64) Options {
   445  	opts := *o
   446  	opts.forwardIndexThreshold = value
   447  	return &opts
   448  }
   449  
   450  func (o *options) ForwardIndexThreshold() float64 {
   451  	return o.forwardIndexThreshold
   452  }
   453  
   454  func (o *options) SetMmapReporter(mmapReporter mmap.Reporter) Options {
   455  	opts := *o
   456  	opts.mmapReporter = mmapReporter
   457  	return &opts
   458  }
   459  
   460  func (o *options) MmapReporter() mmap.Reporter {
   461  	return o.mmapReporter
   462  }
   463  
   464  func (o *options) SetQueryLimits(value limits.QueryLimits) Options {
   465  	opts := *o
   466  	opts.queryLimits = value
   467  	return &opts
   468  }
   469  
   470  func (o *options) QueryLimits() limits.QueryLimits {
   471  	return o.queryLimits
   472  }