Fix bug when reading past newest buffer

This commit is contained in:
Lou Knauer 2021-11-30 13:09:21 +01:00
parent 38d605b6c4
commit 0219c48e78
2 changed files with 35 additions and 12 deletions

View File

@ -82,12 +82,22 @@ func (b *buffer) write(ts int64, value Float) (*buffer, error) {
return b, nil return b, nil
} }
// Return all known values from `from` to `to`. Gaps of information are func (b *buffer) end() int64 {
// represented by NaN. If values at the start or end are missing, return b.start + int64(len(b.data))*b.frequency
// instead of NaN values, the second and thrid return values contain }
// the actual `from`/`to`.
// This function goes back the buffer chain if `from` is older than the // func interpolate(idx int, data []Float) Float {
// currents buffer start. // if idx == 0 || idx+1 == len(data) {
// return NaN
// }
// return (data[idx-1] + data[idx+1]) / 2.0
// }
// Return all known values from `from` to `to`. Gaps of information are represented as NaN.
// Simple linear interpolation is done between the two neighboring cells if possible.
// If values at the start or end are missing, instead of NaN values, the second and thrid
// return values contain the actual `from`/`to`.
// This function goes back the buffer chain if `from` is older than the currents buffer start.
// The loaded values are added to `data` and `data` is returned, possibly with a shorter length. // The loaded values are added to `data` and `data` is returned, possibly with a shorter length.
// If `data` is not long enough to hold all values, this function will panic! // If `data` is not long enough to hold all values, this function will panic!
func (b *buffer) read(from, to int64, data []Float) ([]Float, int64, int64, error) { func (b *buffer) read(from, to int64, data []Float) ([]Float, int64, int64, error) {
@ -103,10 +113,10 @@ func (b *buffer) read(from, to int64, data []Float) ([]Float, int64, int64, erro
for ; t < to; t += b.frequency { for ; t < to; t += b.frequency {
idx := int((t - b.start) / b.frequency) idx := int((t - b.start) / b.frequency)
if idx >= cap(b.data) { if idx >= cap(b.data) {
b = b.next if b.next == nil {
if b == nil { break
return data, from, t, nil
} }
b = b.next
idx = 0 idx = 0
} }
@ -117,6 +127,8 @@ func (b *buffer) read(from, to int64, data []Float) ([]Float, int64, int64, erro
data[i] += NaN data[i] += NaN
} else if t < b.start { } else if t < b.start {
data[i] += NaN data[i] += NaN
// } else if b.data[idx].IsNaN() {
// data[i] += interpolate(idx, b.data)
} else { } else {
data[i] += b.data[idx] data[i] += b.data[idx]
} }
@ -129,7 +141,7 @@ func (b *buffer) read(from, to int64, data []Float) ([]Float, int64, int64, erro
// Free up and free all buffers in the chain only containing data // Free up and free all buffers in the chain only containing data
// older than `t`. // older than `t`.
func (b *buffer) free(t int64) (int, error) { func (b *buffer) free(t int64) (int, error) {
end := b.start + int64(len(b.data))*b.frequency end := b.end()
if end < t && b.next != nil { if end < t && b.next != nil {
b.next.prev = nil b.next.prev = nil
n := 0 n := 0
@ -167,8 +179,7 @@ func (b *buffer) iterFromTo(from, to int64, callback func(b *buffer) error) erro
return err return err
} }
end := b.start + int64(len(b.data))*b.frequency if from <= b.end() && b.start <= to {
if from <= end && b.start <= to {
return callback(b) return callback(b)
} }

View File

@ -92,6 +92,18 @@ func TestMemoryStoreOutOfBounds(t *testing.T) {
t.Fatalf("Wrong data (got: %d, %f, %f, expected: %d, %f, %f)", t.Fatalf("Wrong data (got: %d, %f, %f, expected: %d, %f, %f)",
len(data), data[0], data[len(data)-1], count, 0., Float(count-1)) len(data), data[0], data[len(data)-1], count, 0., Float(count-1))
} }
testfrom, testlen := int64(100000000), int64(10000)
data, from, to, err = store.Read(sel, "a", testfrom, testfrom+testlen)
if len(data) != 0 || from != testfrom || to != testfrom || err != nil {
t.Fatal("Unexpected data returned when reading range after valid data")
}
testfrom, testlen = 0, 10
data, from, to, err = store.Read(sel, "a", testfrom, testfrom+testlen)
if len(data) != 0 || from != int64(toffset) || to != int64(toffset) || err != nil {
t.Fatal("Unexpected data returned when reading range before valid data")
}
} }
func TestMemoryStoreMissingDatapoints(t *testing.T) { func TestMemoryStoreMissingDatapoints(t *testing.T) {