github.com/m3db/m3@v1.5.0/src/query/functions/utils/metadata.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 utils 22 23 import ( 24 "bytes" 25 26 "github.com/m3db/m3/src/query/block" 27 "github.com/m3db/m3/src/query/models" 28 ) 29 30 // FlattenMetadata applies all shared tags from Metadata to each SeriesMeta 31 func FlattenMetadata( 32 meta block.Metadata, 33 seriesMeta []block.SeriesMeta, 34 ) []block.SeriesMeta { 35 for i, metas := range seriesMeta { 36 seriesMeta[i].Tags = metas.Tags.Add(meta.Tags) 37 } 38 39 return seriesMeta 40 } 41 42 // DedupeMetadata applies all shared tags from Metadata to each SeriesMeta 43 func DedupeMetadata( 44 seriesMeta []block.SeriesMeta, 45 tagOptions models.TagOptions, 46 ) (models.Tags, []block.SeriesMeta) { 47 if len(seriesMeta) == 0 { 48 return models.NewTags(0, tagOptions), seriesMeta 49 } 50 51 commonKeys := make([][]byte, 0, seriesMeta[0].Tags.Len()) 52 commonTags := make(map[string][]byte, seriesMeta[0].Tags.Len()) 53 // For each tag in the first series, read through list of seriesMetas; 54 // if key not found or value differs, this is not a shared tag 55 var distinct bool 56 for _, t := range seriesMeta[0].Tags.Tags { 57 distinct = false 58 for _, metas := range seriesMeta[1:] { 59 if val, ok := metas.Tags.Get(t.Name); ok { 60 if !bytes.Equal(val, t.Value) { 61 distinct = true 62 break 63 } 64 } else { 65 distinct = true 66 break 67 } 68 } 69 70 if !distinct { 71 // This is a shared tag; add it to shared meta 72 commonKeys = append(commonKeys, t.Name) 73 commonTags[string(t.Name)] = t.Value 74 } 75 } 76 77 for i, meta := range seriesMeta { 78 seriesMeta[i].Tags = meta.Tags.TagsWithoutKeys(commonKeys) 79 } 80 81 tags := models.NewTags(len(commonTags), tagOptions) 82 for n, v := range commonTags { 83 tags = tags.AddTag(models.Tag{Name: []byte(n), Value: v}) 84 } 85 86 return tags, seriesMeta 87 }