// ReadSeriesKeyFromSegments returns a series key from an offset within a set of segments.
349707
func ReadSeriesKeyFromSegments(a []*SeriesSegment, offset int64) []byte {
	segmentID, pos := SplitSeriesOffset(offset)
	segment := FindSegment(a, segmentID)
	if segment == nil {
		return nil
	}
	buf := segment.Slice(pos)
	key, _ := ReadSeriesKey(buf)
	return key
}
1008414
func (s *SeriesIDSet) Slice() []uint64 {
	s.RLock()
	defer s.RUnlock()

	a := make([]uint64, 0, s.bitmap.GetCardinality())
	for _, seriesID := range s.bitmap.ToArray() {
		a = append(a, uint64(seriesID))
	}
	return a
}
696994
func KeyValuesFromLine(line []byte, currentLine int) (Pair, error) {
	kv := Pair{}

	if !utf8.Valid(line) {
		return kv, fmt.Errorf("line %d has invalid utf8 bytes : %v", line, string(line))
	}

	// We trim UTF8 BOM from the first line of the file but no others
	if currentLine == 0 {
		line = bytes.TrimPrefix(line, utf8bom)
	}

	// trim the line from all leading whitespace first
	line = bytes.TrimLeftFunc(line, unicode.IsSpace)

	// If the line is empty or a comment, we return a blank key/value pair.
	if len(line) == 0 || line[0] == '#' {
		return kv, nil
	}

	data := strings.SplitN(string(line), "=", 2)
	key := data[0]
	if errs := validation.IsEnvVarName(key); len(errs) != 0 {
		return kv, fmt.Errorf("%q is not a valid key name: %s", key, strings.Join(errs, ";"))
	}

	if len(data) == 2 {
		kv.Value = data[1]
	} else {
		// No value (no `=` in the line) is a signal to obtain the value
		// from the environment.
		kv.Value = os.Getenv(key)
	}
	kv.Key = key
	return kv, nil
}
1262716
func (f *SeriesFile) SeriesKey(id SeriesID) []byte {
	if id.IsZero() {
		return nil
	}
	p := f.SeriesIDPartition(id)
	if p == nil {
		return nil
	}
	return p.SeriesKey(id)
}
481868
func ParseSeriesSegmentFilename(filename string) (uint16, error) {
	i, err := strconv.ParseUint(filename, 16, 32)
	return uint16(i), err
}
12839
func parseEncryptionKeys(sseKeys string) (encMap map[string][]prefixSSEPair, err *probe.Error) {
	encMap = make(map[string][]prefixSSEPair)
	if sseKeys == "" {
		return
	}
	prefix := ""
	index := 0 // start index of prefix
	vs := 0    // start index of sse-c key
	sseKeyLen := 32
	delim := 1
	k := len(sseKeys)
	for index < k {
		i := strings.Index(sseKeys[index:], "=")
		if i == -1 {
			return nil, probe.NewError(errors.New("SSE-C prefix should be of the form prefix1=key1,... "))
		}
		prefix = sseKeys[index : index+i]
		alias, _ := url2Alias(prefix)
		vs = i + 1 + index
		if vs+32 > k {
			return nil, probe.NewError(errors.New("SSE-C key should be 32 bytes long"))
		}
		if (vs+sseKeyLen < k) && sseKeys[vs+sseKeyLen] != ',' {
			return nil, probe.NewError(errors.New("SSE-C prefix=secret should be delimited by , and secret should be 32 bytes long"))
		}
		sseKey := sseKeys[vs : vs+sseKeyLen]
		if _, ok := encMap[alias]; !ok {
			encMap[alias] = make([]prefixSSEPair, 0)
		}
		sse, e := encrypt.NewSSEC([]byte(sseKey))
		if e != nil {
			return nil, probe.NewError(e)
		}
		encMap[alias] = append(encMap[alias], prefixSSEPair{
			Prefix: prefix,
			SSE:    sse,
		})
		// advance index sseKeyLen + delim bytes for the next key start
		index = vs + sseKeyLen + delim
	}

	// Sort encryption keys in descending order of prefix length
	for _, encKeys := range encMap {
		sort.Sort(byPrefixLength(encKeys))
	}

	// Success.
	return encMap, nil
}
159841
func (l *Client) GetSegments(table string) ([]*Segment, error) {
	res := ApiResp{}
	data := []*Segment{}
	params := url.Values{}

	params.Add("table", table)

	// make the request
	err := l.Get(segmentListEndpoint, params, nil, &res, &data)
	if err != nil {
		return data, err
	}

	return data, nil
}
1303749
func ParseKeyValues(input string, out map[string]string, sep string) error {
	if out == nil {
		return fmt.Errorf("'out is nil")
	}

	keyValues := ParseDedupLowercaseAndSortStrings(input, sep)
	if len(keyValues) == 0 {
		return nil
	}

	for _, keyValue := range keyValues {
		shards := strings.Split(keyValue, "=")
		if len(shards) != 2 {
			return fmt.Errorf("invalid <key,value> format")
		}

		key := strings.TrimSpace(shards[0])
		value := strings.TrimSpace(shards[1])
		if key == "" || value == "" {
			return fmt.Errorf("invalid <key,value> pair: key: %q value: %q", key, value)
		}
		out[key] = value
	}
	return nil
}
848643
func (i *Index) CreateSeriesListIfNotExists(collection *tsdb.SeriesCollection) error {
	// Create the series list on the series file first. This validates all of the types for
	// the collection.
	err := i.sfile.CreateSeriesListIfNotExists(collection)
	if err != nil {
		return err
	}

	// We need to move different series into collections for each partition
	// to process.
	pCollections := make([]tsdb.SeriesCollection, i.PartitionN)

	// Determine partition for series using each series key.
	for iter := collection.Iterator(); iter.Next(); {
		pCollection := &pCollections[i.partitionIdx(iter.Key())]
		pCollection.Names = append(pCollection.Names, iter.Name())
		pCollection.Tags = append(pCollection.Tags, iter.Tags())
		pCollection.SeriesIDs = append(pCollection.SeriesIDs, iter.SeriesID())
	}

	// Process each subset of series on each partition.
	n := i.availableThreads()

	// Store errors.
	errC := make(chan error, i.PartitionN)

	var pidx uint32 // Index of maximum Partition being worked on.
	for k := 0; k < n; k++ {
		go func() {
			i.mu.RLock()
			partitionN := len(i.partitions)
			i.mu.RUnlock()

			for {
				idx := int(atomic.AddUint32(&pidx, 1) - 1) // Get next partition to work on.
				if idx >= partitionN {
					return // No more work.
				}

				i.mu.RLock()
				partition := i.partitions[idx]
				i.mu.RUnlock()

				ids, err := partition.createSeriesListIfNotExists(&pCollections[idx])
				if len(ids) == 0 {
					errC <- err
					continue
				}

				// Some cached bitset results may need to be updated.
				i.tagValueCache.RLock()
				for j, id := range ids {
					if id.IsZero() {
						continue
					}

					name := pCollections[idx].Names[j]
					tags := pCollections[idx].Tags[j]
					if i.tagValueCache.measurementContainsSets(name) {
						for _, pair := range tags {
							// TODO(edd): It's not clear to me yet whether it will be better to take a lock
							// on every series id set, or whether to gather them all up under the cache rlock
							// and then take the cache lock and update them all at once (without invoking a lock
							// on each series id set).
							//
							// Taking the cache lock will block all queries, but is one lock. Taking each series set
							// lock might be many lock/unlocks but will only block a query that needs that particular set.
							//
							// Need to think on it, but I think taking a lock on each series id set is the way to go.
							//
							// One other option here is to take a lock on the series id set when we first encounter it
							// and then keep it locked until we're done with all the ids.
							//
							// Note: this will only add `id` to the set if it exists.
							i.tagValueCache.addToSet(name, pair.Key, pair.Value, id) // Takes a lock on the series id set
						}
					}
				}
				i.tagValueCache.RUnlock()

				errC <- err
			}
		}()
	}

	// Check for error
	for i := 0; i < cap(errC); i++ {
		if err := <-errC; err != nil {
			return err
		}
	}

	return nil
}
225543
func (p *SeriesPartition) Series(id SeriesID) ([]byte, models.Tags) {
	key := p.SeriesKey(id)
	if key == nil {
		return nil, nil
	}
	return ParseSeriesKey(key)
}
913807
func JoinSeriesOffset(segmentID uint16, pos uint32) int64 {
	return (int64(segmentID) << 32) | int64(pos)
}
918924
func (s *SeriesSegment) ForEachEntry(fn func(flag uint8, id SeriesIDTyped, offset int64, key []byte) error) error {
	for pos := uint32(SeriesSegmentHeaderSize); pos < uint32(len(s.data)); {
		flag, id, key, sz := ReadSeriesEntry(s.data[pos:])
		if !IsValidSeriesEntryFlag(flag) {
			break
		}

		offset := JoinSeriesOffset(s.id, pos)
		if err := fn(flag, id, offset, key); err != nil {
			return err
		}
		pos += uint32(sz)
	}
	return nil
}
398875
func ReadSymbols(bs ByteSlice, version int, off int) ([]string, map[uint32]string, error) {
	if off == 0 {
		return nil, nil, nil
	}
	d := encoding.NewDecbufAt(bs, off, castagnoliTable)

	var (
		origLen     = d.Len()
		cnt         = d.Be32int()
		basePos     = uint32(off) + 4
		nextPos     = basePos + uint32(origLen-d.Len())
		symbolSlice []string
		symbols     = map[uint32]string{}
	)
	if version == FormatV2 {
		symbolSlice = make([]string, 0, cnt)
	}

	for d.Err() == nil && d.Len() > 0 && cnt > 0 {
		s := d.UvarintStr()

		if version == FormatV2 {
			symbolSlice = append(symbolSlice, s)
		} else {
			symbols[nextPos] = s
			nextPos = basePos + uint32(origLen-d.Len())
		}
		cnt--
	}
	return symbolSlice, symbols, errors.Wrap(d.Err(), "read symbols")
}
1347928
func SeriesAndFieldFromCompositeKey(key []byte) ([]byte, []byte) {
	sep := bytes.Index(key, keyFieldSeparatorBytes)
	if sep == -1 {
		// No field???
		return key, nil
	}
	return key[:sep], key[sep+len(keyFieldSeparator):]
}
478906
func ReadLabels(bkt *bolt.Bucket) (map[string]string, error) {
	return readMap(bkt, bucketKeyLabels)
}
171041
func parseSeriesKey(data []byte, dst models.Tags) ([]byte, models.Tags) {
	var name []byte
	_, data = ReadSeriesKeyLen(data)
	name, data = ReadSeriesKeyMeasurement(data)
	tagN, data := ReadSeriesKeyTagN(data)

	dst = dst[:cap(dst)] // Grow dst to use full capacity
	if got, want := len(dst), tagN; got < want {
		dst = append(dst, make(models.Tags, want-got)...)
	} else if got > want {
		dst = dst[:want]
	}
	dst = dst[:tagN]

	for i := 0; i < tagN; i++ {
		var key, value []byte
		key, value, data = ReadSeriesKeyTag(data)
		dst[i].Key, dst[i].Value = key, value
	}

	return name, dst
}
254386
func (g *groupResultSet) seriesHasPoints(row *SeriesRow) bool {
	// TODO(sgc): this is expensive. Storage engine must provide efficient time range queries of series keys.
	cur := g.mb.createCursor(*row)
	var ts []int64
	switch c := cur.(type) {
	case cursors.IntegerArrayCursor:
		a := c.Next()
		ts = a.Timestamps
	case cursors.FloatArrayCursor:
		a := c.Next()
		ts = a.Timestamps
	case cursors.UnsignedArrayCursor:
		a := c.Next()
		ts = a.Timestamps
	case cursors.BooleanArrayCursor:
		a := c.Next()
		ts = a.Timestamps
	case cursors.StringArrayCursor:
		a := c.Next()
		ts = a.Timestamps
	case nil:
		return false
	default:
		panic(fmt.Sprintf("unreachable: %T", c))
	}
	cur.Close()
	return len(ts) > 0
}