github.com/m3db/m3@v1.5.0/src/query/functions/tag/base.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 tag 22 23 import ( 24 "fmt" 25 26 "github.com/m3db/m3/src/query/block" 27 "github.com/m3db/m3/src/query/executor/transform" 28 "github.com/m3db/m3/src/query/models" 29 "github.com/m3db/m3/src/query/parser" 30 ) 31 32 // Applies the given transform to block tags and series tags. 33 type tagTransformFunc func( 34 block.Metadata, 35 []block.SeriesMeta, 36 ) (block.Metadata, []block.SeriesMeta) 37 38 // NewTagOp creates a new tag transform operation. 39 func NewTagOp( 40 opType string, 41 params []string, 42 ) (parser.Params, error) { 43 var ( 44 fn tagTransformFunc 45 err error 46 ) 47 48 switch opType { 49 case TagJoinType: 50 fn, err = makeTagJoinFunc(params) 51 case TagReplaceType: 52 fn, err = makeTagReplaceFunc(params) 53 default: 54 return nil, fmt.Errorf("operator not supported: %s", opType) 55 } 56 57 if err != nil { 58 return nil, err 59 } 60 61 return newBaseOp(opType, fn), nil 62 } 63 64 // baseOp stores required properties for the baseOp. 65 type baseOp struct { 66 opType string 67 tagFn tagTransformFunc 68 } 69 70 func (o baseOp) OpType() string { 71 return o.opType 72 } 73 74 func (o baseOp) String() string { 75 return fmt.Sprintf("type: %s", o.OpType()) 76 } 77 78 // Node creates a tag execution node. 79 func (o baseOp) Node( 80 controller *transform.Controller, 81 _ transform.Options, 82 ) transform.OpNode { 83 return &baseNode{ 84 op: o, 85 controller: controller, 86 } 87 } 88 89 func newBaseOp(opType string, tagFn tagTransformFunc) baseOp { 90 return baseOp{ 91 opType: opType, 92 tagFn: tagFn, 93 } 94 } 95 96 type baseNode struct { 97 op baseOp 98 controller *transform.Controller 99 } 100 101 func (n *baseNode) Params() parser.Params { 102 return n.op 103 } 104 105 func (n *baseNode) Process( 106 queryCtx *models.QueryContext, 107 ID parser.NodeID, 108 b block.Block, 109 ) error { 110 return transform.ProcessSimpleBlock(n, n.controller, queryCtx, ID, b) 111 } 112 113 func (n *baseNode) ProcessBlock( 114 queryCtx *models.QueryContext, 115 ID parser.NodeID, 116 b block.Block, 117 ) (block.Block, error) { 118 it, err := b.StepIter() 119 if err != nil { 120 return nil, err 121 } 122 123 meta := b.Meta() 124 seriesMeta := it.SeriesMeta() 125 meta, seriesMeta = n.op.tagFn(meta, seriesMeta) 126 lazyOpts := block.NewLazyOptions(). 127 SetMetaTransform( 128 func(block.Metadata) block.Metadata { return meta }, 129 ). 130 SetSeriesMetaTransform( 131 func([]block.SeriesMeta) []block.SeriesMeta { return seriesMeta }, 132 ) 133 134 return block.NewLazyBlock(b, lazyOpts), nil 135 }