mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Fix compaction range selection
This commit is contained in:
parent
3c22488157
commit
5d7b5994d6
15
compact.go
15
compact.go
|
@ -229,11 +229,24 @@ func splitByRange(ds []dirMeta, tr int64) [][]dirMeta {
|
||||||
|
|
||||||
for i := 0; i < len(ds); {
|
for i := 0; i < len(ds); {
|
||||||
var group []dirMeta
|
var group []dirMeta
|
||||||
|
var t0 int64
|
||||||
|
m := ds[i].meta
|
||||||
// Compute start of aligned time range of size tr closest to the current block's start.
|
// Compute start of aligned time range of size tr closest to the current block's start.
|
||||||
t0 := ds[i].meta.MinTime - (ds[i].meta.MinTime % tr)
|
if m.MinTime >= 0 {
|
||||||
|
t0 = tr * (m.MinTime / tr)
|
||||||
|
} else {
|
||||||
|
t0 = tr * ((m.MinTime - tr + 1) / tr)
|
||||||
|
}
|
||||||
|
// Skip blocks that don't fall into the range. This can happen via mis-alignment or
|
||||||
|
// by being the multiple of the intended range.
|
||||||
|
if ds[i].meta.MinTime < t0 || ds[i].meta.MaxTime > t0+tr {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Add all dirs to the current group that are within [t0, t0+tr].
|
// Add all dirs to the current group that are within [t0, t0+tr].
|
||||||
for ; i < len(ds); i++ {
|
for ; i < len(ds); i++ {
|
||||||
|
// Either the block falls into the next range or doesn't fit at all (checked above).
|
||||||
if ds[i].meta.MinTime < t0 || ds[i].meta.MaxTime > t0+tr {
|
if ds[i].meta.MinTime < t0 || ds[i].meta.MaxTime > t0+tr {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
package tsdb
|
package tsdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -178,58 +177,84 @@ func TestCompactionSelect(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSplitByRange(t *testing.T) {
|
func TestSplitByRange(t *testing.T) {
|
||||||
splitterFunc := func(ds []dirMeta, tr int64) [][]dirMeta {
|
|
||||||
rMap := make(map[int64][]dirMeta)
|
|
||||||
for _, dir := range ds {
|
|
||||||
t0 := dir.meta.MinTime - dir.meta.MinTime%tr
|
|
||||||
if intervalContains(t0, t0+tr, dir.meta.MinTime) && intervalContains(t0, t0+tr, dir.meta.MaxTime) {
|
|
||||||
rMap[t0] = append(rMap[t0], dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res := make([][]dirMeta, 0, len(rMap))
|
|
||||||
for _, v := range rMap {
|
|
||||||
res = append(res, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(res, func(i, j int) bool {
|
|
||||||
return res[i][0].meta.MinTime < res[j][0].meta.MinTime
|
|
||||||
})
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
trange int64
|
trange int64
|
||||||
ranges [][]int64
|
ranges [][2]int64
|
||||||
output [][][]int64
|
output [][][2]int64
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
trange: 60,
|
trange: 60,
|
||||||
ranges: [][]int64{{0, 10}},
|
ranges: [][2]int64{{0, 10}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{0, 10}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
trange: 60,
|
trange: 60,
|
||||||
ranges: [][]int64{{0, 60}},
|
ranges: [][2]int64{{0, 60}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{0, 60}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
trange: 60,
|
trange: 60,
|
||||||
ranges: [][]int64{{0, 10}, {30, 60}},
|
ranges: [][2]int64{{0, 10}, {9, 15}, {30, 60}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{0, 10}, {9, 15}, {30, 60}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
trange: 60,
|
trange: 60,
|
||||||
ranges: [][]int64{{0, 10}, {60, 90}},
|
ranges: [][2]int64{{70, 90}, {125, 130}, {130, 180}, {1000, 1001}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{70, 90}},
|
||||||
|
{{125, 130}, {130, 180}},
|
||||||
|
{{1000, 1001}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Mis-aligned or too-large blocks are ignored.
|
||||||
|
{
|
||||||
|
trange: 60,
|
||||||
|
ranges: [][2]int64{{50, 70}, {70, 80}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{70, 80}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
trange: 72,
|
||||||
|
ranges: [][2]int64{{0, 144}, {144, 216}, {216, 288}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{144, 216}},
|
||||||
|
{{216, 288}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Various awkward edge cases easy to hit with negative numbers.
|
||||||
|
{
|
||||||
|
trange: 60,
|
||||||
|
ranges: [][2]int64{{-10, -5}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{-10, -5}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
trange: 60,
|
trange: 60,
|
||||||
ranges: [][]int64{{0, 10}, {20, 30}, {90, 120}},
|
ranges: [][2]int64{{-60, -50}, {-10, -5}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{-60, -50}, {-10, -5}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
trange: 60,
|
trange: 60,
|
||||||
ranges: [][]int64{{0, 10}, {59, 60}, {60, 120}, {120, 180}, {190, 200}, {200, 210}, {220, 239}},
|
ranges: [][2]int64{{-60, -50}, {-10, -5}, {0, 15}},
|
||||||
|
output: [][][2]int64{
|
||||||
|
{{-60, -50}, {-10, -5}},
|
||||||
|
{{0, 15}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
|
// Transform input range tuples into dirMetas.
|
||||||
blocks := make([]dirMeta, 0, len(c.ranges))
|
blocks := make([]dirMeta, 0, len(c.ranges))
|
||||||
for _, r := range c.ranges {
|
for _, r := range c.ranges {
|
||||||
blocks = append(blocks, dirMeta{
|
blocks = append(blocks, dirMeta{
|
||||||
|
@ -240,6 +265,16 @@ func TestSplitByRange(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Equal(t, splitterFunc(blocks, c.trange), splitByRange(blocks, c.trange))
|
// Transform output range tuples into dirMetas.
|
||||||
|
exp := make([][]dirMeta, len(c.output))
|
||||||
|
for i, group := range c.output {
|
||||||
|
for _, r := range group {
|
||||||
|
exp[i] = append(exp[i], dirMeta{
|
||||||
|
meta: &BlockMeta{MinTime: r[0], MaxTime: r[1]},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, exp, splitByRange(blocks, c.trange))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue