// Ensure that deletes only sent to the WAL will clear out the data from the cache on restart func TestEngine_DeleteWALLoadMetadata(t *testing.T) { e := MustOpenEngine() defer e.Close() if err := e.WritePointsString( `cpu,host=A value=1.1 1000000000`, `cpu,host=B value=1.2 2000000000`, ); err != nil { t.Fatalf("failed to write points: %s", err.Error()) } // Remove series. if err := e.DeleteSeries([]string{"cpu,host=A"}); err != nil { t.Fatalf("failed to delete series: %s", err.Error()) } // Ensure we can close and load index from the WAL if err := e.Reopen(); err != nil { t.Fatal(err) } if exp, got := 0, len(e.Cache.Values(tsm1.SeriesFieldKey("cpu,host=A", "value"))); exp != got { t.Fatalf("unexpected number of values: got: %d. exp: %d", got, exp) } if exp, got := 1, len(e.Cache.Values(tsm1.SeriesFieldKey("cpu,host=B", "value"))); exp != got { t.Fatalf("unexpected number of values: got: %d. exp: %d", got, exp) } }
// Next returns whether any data remains to be read. It must be called before // the next call to Read(). func (r *Reader) Next() bool { r.valuePos = 0 OUTER: for { if r.currCursor >= len(r.cursors) { // All cursors drained. No more data remains. return false } cc := r.cursors[r.currCursor] r.keyBuf = tsm1.SeriesFieldKey(cc.series, cc.field) for { k, v := cc.Next() if k == -1 { // Go to next cursor and try again. r.currCursor++ if r.valuePos == 0 { // The previous cursor had no data. Instead of returning // just go immediately to the next cursor. continue OUTER } // There is some data available. Indicate that it should be read. return true } if f, ok := v.(float64); ok { if math.IsInf(f, 0) { r.stats.AddPointsRead(1) r.stats.IncrInf() continue } if math.IsNaN(f) { r.stats.AddPointsRead(1) r.stats.IncrNaN() continue } } r.values[r.valuePos] = tsm1.NewValue(k, v) r.valuePos++ if r.valuePos >= len(r.values) { return true } } } }