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 }