| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | // Copyright 2021 The Prometheus Authors
 | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package storage | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"math" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 04:49:25 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/model/histogram" | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/tsdb/chunkenc" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-15 16:27:20 +08:00
										 |  |  | // MemoizedSeriesIterator wraps an iterator with a buffer to look back the previous element.
 | 
					
						
							| 
									
										
										
										
											2023-05-01 04:13:25 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | // This iterator regards integer histograms as float histograms; calls to Seek() will never return chunkenc.Histogram.
 | 
					
						
							|  |  |  | // This iterator deliberately does not implement chunkenc.Iterator.
 | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | type MemoizedSeriesIterator struct { | 
					
						
							|  |  |  | 	it    chunkenc.Iterator | 
					
						
							|  |  |  | 	delta int64 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 04:49:25 +08:00
										 |  |  | 	lastTime  int64 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 	valueType chunkenc.ValueType | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Keep track of the previously returned value.
 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 	prevTime           int64 | 
					
						
							|  |  |  | 	prevValue          float64 | 
					
						
							|  |  |  | 	prevFloatHistogram *histogram.FloatHistogram | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewMemoizedEmptyIterator is like NewMemoizedIterator but it's initialised with an empty iterator.
 | 
					
						
							|  |  |  | func NewMemoizedEmptyIterator(delta int64) *MemoizedSeriesIterator { | 
					
						
							|  |  |  | 	return NewMemoizedIterator(chunkenc.NewNopIterator(), delta) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewMemoizedIterator returns a new iterator that buffers the values within the
 | 
					
						
							|  |  |  | // time range of the current element and the duration of delta before.
 | 
					
						
							|  |  |  | func NewMemoizedIterator(it chunkenc.Iterator, delta int64) *MemoizedSeriesIterator { | 
					
						
							|  |  |  | 	bit := &MemoizedSeriesIterator{ | 
					
						
							|  |  |  | 		delta:    delta, | 
					
						
							|  |  |  | 		prevTime: math.MinInt64, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	bit.Reset(it) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return bit | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Reset the internal state to reuse the wrapper with the provided iterator.
 | 
					
						
							|  |  |  | func (b *MemoizedSeriesIterator) Reset(it chunkenc.Iterator) { | 
					
						
							|  |  |  | 	b.it = it | 
					
						
							|  |  |  | 	b.lastTime = math.MinInt64 | 
					
						
							|  |  |  | 	b.prevTime = math.MinInt64 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 	b.valueType = it.Next() | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // PeekPrev returns the previous element of the iterator. If there is none buffered,
 | 
					
						
							|  |  |  | // ok is false.
 | 
					
						
							| 
									
										
										
										
											2023-04-11 04:07:43 +08:00
										 |  |  | func (b *MemoizedSeriesIterator) PeekPrev() (t int64, v float64, fh *histogram.FloatHistogram, ok bool) { | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	if b.prevTime == math.MinInt64 { | 
					
						
							| 
									
										
										
										
											2023-04-11 04:07:43 +08:00
										 |  |  | 		return 0, 0, nil, false | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-04-11 04:07:43 +08:00
										 |  |  | 	return b.prevTime, b.prevValue, b.prevFloatHistogram, true | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Seek advances the iterator to the element at time t or greater.
 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | func (b *MemoizedSeriesIterator) Seek(t int64) chunkenc.ValueType { | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	t0 := t - b.delta | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-15 20:49:33 +08:00
										 |  |  | 	if b.valueType != chunkenc.ValNone && t0 > b.lastTime { | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 		// Reset the previously stored element because the seek advanced
 | 
					
						
							|  |  |  | 		// more than the delta.
 | 
					
						
							|  |  |  | 		b.prevTime = math.MinInt64 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 		b.valueType = b.it.Seek(t0) | 
					
						
							| 
									
										
										
										
											2023-05-01 04:13:25 +08:00
										 |  |  | 		switch b.valueType { | 
					
						
							|  |  |  | 		case chunkenc.ValNone: | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 			return chunkenc.ValNone | 
					
						
							| 
									
										
										
										
											2023-05-01 04:13:25 +08:00
										 |  |  | 		case chunkenc.ValHistogram: | 
					
						
							|  |  |  | 			b.valueType = chunkenc.ValFloatHistogram | 
					
						
							| 
									
										
										
										
											2021-11-16 03:36:44 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 		b.lastTime = b.it.AtT() | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if b.lastTime >= t { | 
					
						
							| 
									
										
										
										
											2021-11-16 04:49:25 +08:00
										 |  |  | 		return b.valueType | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 	for b.Next() != chunkenc.ValNone { | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 		if b.lastTime >= t { | 
					
						
							| 
									
										
										
										
											2021-11-16 04:49:25 +08:00
										 |  |  | 			return b.valueType | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 	return chunkenc.ValNone | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-01 04:13:25 +08:00
										 |  |  | // Next advances the iterator to the next element. Note that this does not check whether the element being buffered is
 | 
					
						
							|  |  |  | // within the time range of the current element and the duration of delta before.
 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | func (b *MemoizedSeriesIterator) Next() chunkenc.ValueType { | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	// Keep track of the previous element.
 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 	switch b.valueType { | 
					
						
							|  |  |  | 	case chunkenc.ValNone: | 
					
						
							|  |  |  | 		return chunkenc.ValNone | 
					
						
							|  |  |  | 	case chunkenc.ValFloat: | 
					
						
							|  |  |  | 		b.prevTime, b.prevValue = b.it.At() | 
					
						
							|  |  |  | 		b.prevFloatHistogram = nil | 
					
						
							| 
									
										
										
										
											2023-05-01 04:13:25 +08:00
										 |  |  | 	case chunkenc.ValHistogram, chunkenc.ValFloatHistogram: | 
					
						
							| 
									
										
										
										
											2021-11-16 04:49:25 +08:00
										 |  |  | 		b.prevValue = 0 | 
					
						
							| 
									
										
										
										
											2024-01-24 00:02:14 +08:00
										 |  |  | 		b.prevTime, b.prevFloatHistogram = b.it.AtFloatHistogram(nil) | 
					
						
							| 
									
										
										
										
											2021-11-16 03:36:44 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | 	b.valueType = b.it.Next() | 
					
						
							|  |  |  | 	if b.valueType != chunkenc.ValNone { | 
					
						
							|  |  |  | 		b.lastTime = b.it.AtT() | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-05-01 04:13:25 +08:00
										 |  |  | 	if b.valueType == chunkenc.ValHistogram { | 
					
						
							|  |  |  | 		b.valueType = chunkenc.ValFloatHistogram | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-11-16 04:49:25 +08:00
										 |  |  | 	return b.valueType | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-29 18:53:04 +08:00
										 |  |  | // At returns the current float element of the iterator.
 | 
					
						
							|  |  |  | func (b *MemoizedSeriesIterator) At() (int64, float64) { | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | 	return b.it.At() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-29 18:53:04 +08:00
										 |  |  | // AtFloatHistogram returns the current float-histogram element of the iterator.
 | 
					
						
							|  |  |  | func (b *MemoizedSeriesIterator) AtFloatHistogram() (int64, *histogram.FloatHistogram) { | 
					
						
							| 
									
										
										
										
											2024-01-24 00:02:14 +08:00
										 |  |  | 	return b.it.AtFloatHistogram(nil) | 
					
						
							| 
									
										
										
										
											2021-11-29 15:54:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-15 12:09:02 +08:00
										 |  |  | // AtT returns the timestamp of the current element of the iterator.
 | 
					
						
							|  |  |  | func (b *MemoizedSeriesIterator) AtT() int64 { | 
					
						
							|  |  |  | 	return b.it.AtT() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-11 21:32:56 +08:00
										 |  |  | // Err returns the last encountered error.
 | 
					
						
							|  |  |  | func (b *MemoizedSeriesIterator) Err() error { | 
					
						
							|  |  |  | 	return b.it.Err() | 
					
						
							|  |  |  | } |