1// Copyright 2017 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package remote
15
16import (
17	"sort"
18
19	"github.com/prometheus/common/model"
20	"github.com/prometheus/prometheus/storage/local"
21	"github.com/prometheus/prometheus/storage/metric"
22)
23
24// This is a struct and not just a renamed type because otherwise the Metric
25// field and Metric() methods would clash.
26type sampleStreamIterator struct {
27	ss *model.SampleStream
28}
29
30func (it sampleStreamIterator) Metric() metric.Metric {
31	return metric.Metric{Metric: it.ss.Metric}
32}
33
34func (it sampleStreamIterator) ValueAtOrBeforeTime(ts model.Time) model.SamplePair {
35	// TODO: This is a naive inefficient approach - in reality, queries go mostly
36	// linearly through iterators, and we will want to make successive calls to
37	// this method more efficient by taking into account the last result index
38	// somehow (similarly to how it's done in Prometheus's
39	// memorySeriesIterators).
40	i := sort.Search(len(it.ss.Values), func(n int) bool {
41		return it.ss.Values[n].Timestamp.After(ts)
42	})
43	if i == 0 {
44		return model.SamplePair{Timestamp: model.Earliest}
45	}
46	return it.ss.Values[i-1]
47}
48
49func (it sampleStreamIterator) RangeValues(in metric.Interval) []model.SamplePair {
50	n := len(it.ss.Values)
51	start := sort.Search(n, func(i int) bool {
52		return !it.ss.Values[i].Timestamp.Before(in.OldestInclusive)
53	})
54	end := sort.Search(n, func(i int) bool {
55		return it.ss.Values[i].Timestamp.After(in.NewestInclusive)
56	})
57
58	if start == n {
59		return nil
60	}
61
62	return it.ss.Values[start:end]
63}
64
65func (it sampleStreamIterator) Close() {}
66
67// IteratorsToMatrix converts a list of iterators into a model.Matrix.
68func IteratorsToMatrix(iters []local.SeriesIterator, interval metric.Interval) model.Matrix {
69	result := make(model.Matrix, 0, len(iters))
70	for _, iter := range iters {
71		result = append(result, &model.SampleStream{
72			Metric: iter.Metric().Metric,
73			Values: iter.RangeValues(interval),
74		})
75	}
76	return result
77}
78