tombstones: Fixed Add method in order to support trimming time series; Simplified the algo. (#7471)
* tombstones: Fixed Add method in order to support edge trimming; Simplified the algo. Signed-off-by: Bartlomiej Plotka <bwplotka@gmail.com> * Removed duplicated test case. Signed-off-by: Bartlomiej Plotka <bwplotka@gmail.com> * Fixed comment, removed "edge" mention. Signed-off-by: Bartlomiej Plotka <bwplotka@gmail.com> * Removed trimming word. Signed-off-by: Bartlomiej Plotka <bwplotka@gmail.com>
This commit is contained in:
parent
487f1e07ff
commit
1861bf38f5
|
@ -22,6 +22,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
|
@ -286,47 +287,32 @@ type Intervals []Interval
|
|||
|
||||
// Add the new time-range to the existing ones.
|
||||
// The existing ones must be sorted.
|
||||
func (itvs Intervals) Add(n Interval) Intervals {
|
||||
for i, r := range itvs {
|
||||
// TODO(gouthamve): Make this codepath easier to digest.
|
||||
if r.InBounds(n.Mint-1) || r.InBounds(n.Mint) {
|
||||
if n.Maxt > r.Maxt {
|
||||
itvs[i].Maxt = n.Maxt
|
||||
}
|
||||
|
||||
j := 0
|
||||
for _, r2 := range itvs[i+1:] {
|
||||
if n.Maxt < r2.Mint {
|
||||
break
|
||||
}
|
||||
j++
|
||||
}
|
||||
if j != 0 {
|
||||
if itvs[i+j].Maxt > n.Maxt {
|
||||
itvs[i].Maxt = itvs[i+j].Maxt
|
||||
}
|
||||
itvs = append(itvs[:i+1], itvs[i+j+1:]...)
|
||||
}
|
||||
return itvs
|
||||
}
|
||||
|
||||
if r.InBounds(n.Maxt+1) || r.InBounds(n.Maxt) {
|
||||
if n.Mint < r.Maxt {
|
||||
itvs[i].Mint = n.Mint
|
||||
}
|
||||
return itvs
|
||||
}
|
||||
|
||||
if n.Mint < r.Mint {
|
||||
newRange := make(Intervals, i, len(itvs[:i])+1)
|
||||
copy(newRange, itvs[:i])
|
||||
newRange = append(newRange, n)
|
||||
newRange = append(newRange, itvs[i:]...)
|
||||
|
||||
return newRange
|
||||
}
|
||||
func (in Intervals) Add(n Interval) Intervals {
|
||||
if len(in) == 0 {
|
||||
return append(in, n)
|
||||
}
|
||||
// Find min and max indexes of intervals that overlap with the new interval.
|
||||
// Intervals are closed [t1, t2] and t is discreet, so if neighbour intervals are 1 step difference
|
||||
// to the new one, we can merge those together.
|
||||
mini := sort.Search(len(in), func(i int) bool { return in[i].Maxt >= n.Mint-1 })
|
||||
if mini == len(in) {
|
||||
return append(in, n)
|
||||
}
|
||||
|
||||
itvs = append(itvs, n)
|
||||
return itvs
|
||||
maxi := sort.Search(len(in)-mini, func(i int) bool { return in[mini+i].Mint > n.Maxt+1 })
|
||||
if maxi == 0 {
|
||||
if mini == 0 {
|
||||
return append(Intervals{n}, in...)
|
||||
}
|
||||
return append(in[:mini], append(Intervals{n}, in[mini:]...)...)
|
||||
}
|
||||
|
||||
if n.Mint < in[mini].Mint {
|
||||
in[mini].Mint = n.Mint
|
||||
}
|
||||
in[mini].Maxt = in[maxi+mini-1].Maxt
|
||||
if n.Maxt > in[mini].Maxt {
|
||||
in[mini].Maxt = n.Maxt
|
||||
}
|
||||
return append(in[:mini+1], in[maxi+mini:]...)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ package tombstones
|
|||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sync"
|
||||
|
@ -25,7 +26,7 @@ import (
|
|||
"github.com/prometheus/prometheus/util/testutil"
|
||||
)
|
||||
|
||||
func TestWriteAndReadbackTombStones(t *testing.T) {
|
||||
func TestWriteAndReadbackTombstones(t *testing.T) {
|
||||
tmpdir, _ := ioutil.TempDir("", "test")
|
||||
defer func() {
|
||||
testutil.Ok(t, os.RemoveAll(tmpdir))
|
||||
|
@ -80,19 +81,19 @@ func TestAddingNewIntervals(t *testing.T) {
|
|||
},
|
||||
{
|
||||
exist: Intervals{{1, 10}, {12, 20}, {25, 30}},
|
||||
new: Interval{21, 23},
|
||||
exp: Intervals{{1, 10}, {12, 23}, {25, 30}},
|
||||
new: Interval{21, 25},
|
||||
exp: Intervals{{1, 10}, {12, 30}},
|
||||
},
|
||||
{
|
||||
exist: Intervals{{1, 10}, {12, 20}, {25, 30}},
|
||||
new: Interval{22, 23},
|
||||
exp: Intervals{{1, 10}, {12, 20}, {22, 23}, {25, 30}},
|
||||
},
|
||||
{
|
||||
exist: Intervals{{1, 2}, {3, 5}, {7, 7}},
|
||||
new: Interval{6, 7},
|
||||
exp: Intervals{{1, 2}, {3, 7}},
|
||||
},
|
||||
{
|
||||
exist: Intervals{{1, 10}, {12, 20}, {25, 30}},
|
||||
new: Interval{21, 25},
|
||||
exp: Intervals{{1, 10}, {12, 30}},
|
||||
},
|
||||
{
|
||||
exist: Intervals{{1, 10}, {12, 20}, {25, 30}},
|
||||
new: Interval{18, 23},
|
||||
|
@ -123,11 +124,36 @@ func TestAddingNewIntervals(t *testing.T) {
|
|||
new: Interval{1, 3},
|
||||
exp: Intervals{{1, 3}, {5, 10}, {12, 20}, {25, 30}},
|
||||
},
|
||||
{
|
||||
exist: Intervals{{5, 10}, {12, 20}, {25, 30}},
|
||||
new: Interval{35, 40},
|
||||
exp: Intervals{{5, 10}, {12, 20}, {25, 30}, {35, 40}},
|
||||
},
|
||||
{
|
||||
new: Interval{math.MinInt64, 2},
|
||||
exp: Intervals{{math.MinInt64, 2}},
|
||||
},
|
||||
{
|
||||
exist: Intervals{{math.MinInt64, 2}},
|
||||
new: Interval{9, math.MaxInt64},
|
||||
exp: Intervals{{math.MinInt64, 2}, {9, math.MaxInt64}},
|
||||
},
|
||||
{
|
||||
exist: Intervals{{9, math.MaxInt64}},
|
||||
new: Interval{math.MinInt64, 2},
|
||||
exp: Intervals{{math.MinInt64, 2}, {9, math.MaxInt64}},
|
||||
},
|
||||
{
|
||||
exist: Intervals{{9, math.MaxInt64}},
|
||||
new: Interval{math.MinInt64, 10},
|
||||
exp: Intervals{{math.MinInt64, math.MaxInt64}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
|
||||
testutil.Equals(t, c.exp, c.exist.Add(c.new))
|
||||
t.Run("", func(t *testing.T) {
|
||||
testutil.Equals(t, c.exp, c.exist.Add(c.new))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue