github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/tools/blocksconvert/scanner/index_entry.go (about) 1 package scanner 2 3 import ( 4 "bytes" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/pkg/errors" 10 ) 11 12 // v9 (hashValue, rangeRange -> value) 13 // <userID>:d<Index>:metricName, <seriesID>\0\0\0 "7" \0 -> "-" 14 // <userID>:d<Index>:metricName:labelName, sha256(labelValue)\0<seriesID>\0\0 "8" \0 -> labelValue 15 // <userID>:d<Index>:<seriesID>, throughBytes \0\0 chunkID \0 "3" \0 -> "" 16 // 17 // <seriesID> is base64 of SHA256(labels) 18 19 // v10 (hashValue, rangeValue -> value) 20 // <shard>:<userID>:d<Index>:metricName, <seriesID>\0\0\0 "7" \0 -> "-" 21 // <shard>:<userID>:d<Index>:metricName:labelName, sha256(labelValue)\0<seriesID>\0\0 "8" \0 -> labelValue 22 // <userID>:d<Index>:<seriesID>, throughBytes \0\0 chunkID \0 "3" \0 -> "-" 23 // v11 adds: 24 // <seriesID>, \0\0\0 '9' \0 -> JSON array with label values. 25 26 func IsMetricToSeriesMapping(RangeValue []byte) bool { 27 return bytes.HasSuffix(RangeValue, []byte("\0007\000")) 28 } 29 30 func IsMetricLabelToLabelValueMapping(RangeValue []byte) bool { 31 return bytes.HasSuffix(RangeValue, []byte("\0008\000")) 32 } 33 34 func IsSeriesToLabelValues(RangeValue []byte) bool { 35 return bytes.HasSuffix(RangeValue, []byte("\0009\000")) 36 } 37 38 // Series to Chunk mapping uses \0 "3" \0 suffix of range value. 39 func IsSeriesToChunkMapping(RangeValue []byte) bool { 40 return bytes.HasSuffix(RangeValue, []byte("\0003\000")) 41 } 42 43 func UnknownIndexEntryType(RangeValue []byte) string { 44 if len(RangeValue) < 3 { 45 return "too-short" 46 } 47 48 // Take last three characters, and report it back. 49 return fmt.Sprintf("%x", RangeValue[len(RangeValue)-2:]) 50 } 51 52 // e.RangeValue is: "userID:d<Index>:base64(sha256(labels))". Index is integer, base64 doesn't contain ':'. 53 func GetSeriesToChunkMapping(HashValue string, RangeValue []byte) (user string, index int, seriesID string, chunkID string, err error) { 54 s := bytes.Split(RangeValue, []byte("\000")) 55 chunkID = string(s[2]) 56 57 parts := strings.Split(HashValue, ":") 58 if len(parts) < 3 { 59 err = errors.Errorf("not enough parts: %d", len(parts)) 60 return 61 } 62 63 seriesID = parts[len(parts)-1] 64 indexStr := parts[len(parts)-2] 65 if !strings.HasPrefix(indexStr, "d") { // Schema v9 and later uses "day" buckets, prefixed with "d" 66 err = errors.Errorf("invalid index prefix") 67 return 68 } 69 index, err = strconv.Atoi(indexStr[1:]) 70 if err != nil { 71 err = errors.Wrapf(err, "failed to parse index") 72 return 73 } 74 user = strings.Join(parts[:len(parts)-2], ":") 75 return 76 }