github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/storage/stores/series/series_store_utils.go (about) 1 package series 2 3 import ( 4 "strings" 5 "unicode/utf8" 6 7 "github.com/prometheus/common/model" 8 9 "github.com/grafana/loki/pkg/logproto" 10 "github.com/grafana/loki/pkg/storage/chunk" 11 "github.com/grafana/loki/pkg/storage/config" 12 "github.com/grafana/loki/pkg/util" 13 ) 14 15 func filterChunksByTime(from, through model.Time, chunks []chunk.Chunk) []chunk.Chunk { 16 filtered := make([]chunk.Chunk, 0, len(chunks)) 17 for _, chunk := range chunks { 18 if chunk.Through < from || through < chunk.From { 19 continue 20 } 21 filtered = append(filtered, chunk) 22 } 23 return filtered 24 } 25 26 func filterChunkRefsByTime(from, through model.Time, chunks []logproto.ChunkRef) []logproto.ChunkRef { 27 filtered := make([]logproto.ChunkRef, 0, len(chunks)) 28 for _, chunk := range chunks { 29 if chunk.Through < from || through < chunk.From { 30 continue 31 } 32 filtered = append(filtered, chunk) 33 } 34 return filtered 35 } 36 37 func labelNamesFromChunks(chunks []chunk.Chunk) []string { 38 var result util.UniqueStrings 39 for _, c := range chunks { 40 for _, l := range c.Metric { 41 if l.Name == model.MetricNameLabel { 42 continue 43 } 44 45 result.Add(l.Name) 46 } 47 } 48 return result.Strings() 49 } 50 51 func filterChunksByUniqueFingerprint(s config.SchemaConfig, chunks []chunk.Chunk) ([]chunk.Chunk, []string) { 52 filtered := make([]chunk.Chunk, 0, len(chunks)) 53 keys := make([]string, 0, len(chunks)) 54 uniqueFp := map[model.Fingerprint]struct{}{} 55 56 for _, chunk := range chunks { 57 if _, ok := uniqueFp[chunk.FingerprintModel()]; ok { 58 continue 59 } 60 filtered = append(filtered, chunk) 61 keys = append(keys, s.ExternalKey(chunk.ChunkRef)) 62 uniqueFp[chunk.FingerprintModel()] = struct{}{} 63 } 64 return filtered, keys 65 } 66 67 func filterChunkRefsByUniqueFingerprint(s config.SchemaConfig, chunks []logproto.ChunkRef) ([]chunk.Chunk, []string) { 68 filtered := make([]chunk.Chunk, 0, len(chunks)) 69 keys := make([]string, 0, len(chunks)) 70 uniqueFp := map[model.Fingerprint]struct{}{} 71 72 for _, c := range chunks { 73 if _, ok := uniqueFp[c.FingerprintModel()]; ok { 74 continue 75 } 76 filtered = append(filtered, chunk.Chunk{ 77 ChunkRef: c, 78 }) 79 keys = append(keys, s.ExternalKey(c)) 80 uniqueFp[c.FingerprintModel()] = struct{}{} 81 } 82 return filtered, keys 83 } 84 85 func uniqueStrings(cs []string) []string { 86 if len(cs) == 0 { 87 return []string{} 88 } 89 90 result := make([]string, 1, len(cs)) 91 result[0] = cs[0] 92 i, j := 0, 1 93 for j < len(cs) { 94 if result[i] == cs[j] { 95 j++ 96 continue 97 } 98 result = append(result, cs[j]) 99 i++ 100 j++ 101 } 102 return result 103 } 104 105 func intersectStrings(left, right []string) []string { 106 var ( 107 i, j = 0, 0 108 result = []string{} 109 ) 110 for i < len(left) && j < len(right) { 111 if left[i] == right[j] { 112 result = append(result, left[i]) 113 } 114 115 if left[i] < right[j] { 116 i++ 117 } else { 118 j++ 119 } 120 } 121 return result 122 } 123 124 // Bitmap used by func isRegexMetaCharacter to check whether a character needs to be escaped. 125 var regexMetaCharacterBytes [16]byte 126 127 // isRegexMetaCharacter reports whether byte b needs to be escaped. 128 func isRegexMetaCharacter(b byte) bool { 129 return b < utf8.RuneSelf && regexMetaCharacterBytes[b%16]&(1<<(b/16)) != 0 130 } 131 132 func init() { 133 for _, b := range []byte(`.+*?()|[]{}^$`) { 134 regexMetaCharacterBytes[b%16] |= 1 << (b / 16) 135 } 136 } 137 138 // FindSetMatches returns list of values that can be equality matched on. 139 // copied from Prometheus querier.go, removed check for Prometheus wrapper. 140 func FindSetMatches(pattern string) []string { 141 escaped := false 142 sets := []*strings.Builder{{}} 143 for i := 0; i < len(pattern); i++ { 144 if escaped { 145 switch { 146 case isRegexMetaCharacter(pattern[i]): 147 sets[len(sets)-1].WriteByte(pattern[i]) 148 case pattern[i] == '\\': 149 sets[len(sets)-1].WriteByte('\\') 150 default: 151 return nil 152 } 153 escaped = false 154 } else { 155 switch { 156 case isRegexMetaCharacter(pattern[i]): 157 if pattern[i] == '|' { 158 sets = append(sets, &strings.Builder{}) 159 } else { 160 return nil 161 } 162 case pattern[i] == '\\': 163 escaped = true 164 default: 165 sets[len(sets)-1].WriteByte(pattern[i]) 166 } 167 } 168 } 169 matches := make([]string, 0, len(sets)) 170 for _, s := range sets { 171 if s.Len() > 0 { 172 matches = append(matches, s.String()) 173 } 174 } 175 return matches 176 }