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  }