diff --git a/CHANGELOG.md b/CHANGELOG.md index f9b998a6ac0..84539df4c6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - [#7797](https://github.com/influxdata/influxdb/issues/7706): Fix data deleted outside of time range - [#8822](https://github.com/influxdata/influxdb/issues/8822): Fix data dropped incorrectly during compaction - [#9006](https://github.com/influxdata/influxdb/pull/9006): Return `query.ErrQueryInterrupted` for a successful read on `InterruptCh`. +- [#8978](https://github.com/influxdata/influxdb/pull/8978): Copy returned bytes from TSI meta functions. ## v1.3.6 [2017-09-29] diff --git a/pkg/bytesutil/bytesutil.go b/pkg/bytesutil/bytesutil.go index 24d0598f7ec..eb80b34d323 100644 --- a/pkg/bytesutil/bytesutil.go +++ b/pkg/bytesutil/bytesutil.go @@ -65,6 +65,25 @@ func Intersect(a, b [][]byte) [][]byte { return other } +// Clone returns a copy of b. +func Clone(b []byte) []byte { + if b == nil { + return nil + } + buf := make([]byte, len(b)) + copy(buf, b) + return buf +} + +// CloneSlice returns a copy of a slice of byte slices. +func CloneSlice(a [][]byte) [][]byte { + other := make([][]byte, len(a)) + for i := range a { + other[i] = Clone(a[i]) + } + return other +} + type byteSlices [][]byte func (a byteSlices) Len() int { return len(a) } diff --git a/tsdb/index/tsi1/index.go b/tsdb/index/tsi1/index.go index 0b32008c8bf..90aac1871c6 100644 --- a/tsdb/index/tsi1/index.go +++ b/tsdb/index/tsi1/index.go @@ -17,6 +17,7 @@ import ( "github.com/influxdata/influxdb/influxql" "github.com/influxdata/influxdb/models" + "github.com/influxdata/influxdb/pkg/bytesutil" "github.com/influxdata/influxdb/pkg/estimator" "github.com/influxdata/influxdb/tsdb" "github.com/uber-go/zap" @@ -382,6 +383,8 @@ func (i *Index) MeasurementNamesByExpr(expr influxql.Expr) ([][]byte, error) { fs := i.RetainFileSet() defer fs.Release() return fs.MeasurementNamesByExpr(expr) + names, err := fs.MeasurementNamesByExpr(expr) + return bytesutil.CloneSlice(names), err } func (i *Index) MeasurementNamesByRegex(re *regexp.Regexp) ([][]byte, error) { @@ -392,7 +395,7 @@ func (i *Index) MeasurementNamesByRegex(re *regexp.Regexp) ([][]byte, error) { var a [][]byte for e := itr.Next(); e != nil; e = itr.Next() { if re.Match(e.Name()) { - a = append(a, e.Name()) + a = append(a, bytesutil.Clone(e.Name())) } } return a, nil @@ -714,7 +717,8 @@ func (i *Index) TagKeyCardinality(name, key []byte) int { func (i *Index) MeasurementSeriesKeysByExpr(name []byte, expr influxql.Expr) ([][]byte, error) { fs := i.RetainFileSet() defer fs.Release() - return fs.MeasurementSeriesKeysByExpr(name, expr, i.fieldset) + keys, err := fs.MeasurementSeriesKeysByExpr(name, expr, i.fieldset) + return bytesutil.CloneSlice(keys), err } // TagSets returns an ordered list of tag sets for a measurement by dimension diff --git a/tsdb/index/tsi1/index_files.go b/tsdb/index/tsi1/index_files.go index 1cb6f22e736..fb8f5df95b3 100644 --- a/tsdb/index/tsi1/index_files.go +++ b/tsdb/index/tsi1/index_files.go @@ -8,6 +8,7 @@ import ( "sort" "time" + "github.com/influxdata/influxdb/pkg/bytesutil" "github.com/influxdata/influxdb/pkg/estimator/hll" "github.com/influxdata/influxdb/pkg/mmap" ) @@ -52,7 +53,7 @@ func (p *IndexFiles) MeasurementNames() [][]byte { itr := p.MeasurementIterator() var names [][]byte for e := itr.Next(); e != nil; e = itr.Next() { - names = append(names, copyBytes(e.Name())) + names = append(names, bytesutil.Clone(e.Name())) } sort.Sort(byteSlices(names)) return names diff --git a/tsdb/index/tsi1/tsi1.go b/tsdb/index/tsi1/tsi1.go index 775ee1e99d9..c3928decae2 100644 --- a/tsdb/index/tsi1/tsi1.go +++ b/tsdb/index/tsi1/tsi1.go @@ -791,16 +791,6 @@ func (a byteSlices) Len() int { return len(a) } func (a byteSlices) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a byteSlices) Less(i, j int) bool { return bytes.Compare(a[i], a[j]) == -1 } -// copyBytes returns a copy of b. -func copyBytes(b []byte) []byte { - if b == nil { - return nil - } - buf := make([]byte, len(b)) - copy(buf, b) - return buf -} - // assert will panic with a given formatted message if the given condition is false. func assert(condition bool, msg string, v ...interface{}) { if !condition {