// Next returns whether there is any more data to be read. func (r *Reader) Next() bool { for { if r.currCursor == len(r.cursors) { // All cursors drained. No more data remains. return false } cc := r.cursors[r.currCursor] k, v := cc.Next() if k == -1 { // Go to next cursor and try again. r.currCursor++ if len(r.valuesBuf) == 0 { // The previous cursor had no data. Instead of returning // just go immediately to the next cursor. continue } // There is some data available. Indicate that it should be read. return true } r.keyBuf = tsm.SeriesFieldKey(cc.series, cc.field) r.valuesBuf = append(r.valuesBuf, tsdb.ConvertToValue(k, v)) if len(r.valuesBuf) == r.ChunkSize { return true } } }
func TestLog_TestWriteQueryOpen(t *testing.T) { w := NewLog() defer w.Close() // Mock call to the index. var vals map[string]tsm1.Values var fields map[string]*tsdb.MeasurementFields var series []*tsdb.SeriesCreate w.IndexWriter.WriteFn = func(valuesByKey map[string]tsm1.Values, measurementFieldsToSave map[string]*tsdb.MeasurementFields, seriesToCreate []*tsdb.SeriesCreate) error { vals = valuesByKey fields = measurementFieldsToSave series = seriesToCreate return nil } if err := w.Open(); err != nil { t.Fatalf("error opening: %s", err.Error()) } p1 := parsePoint("cpu,host=A value=1.1 1000000000") p2 := parsePoint("cpu,host=B value=1.2 1000000000") p3 := parsePoint("cpu,host=A value=2.1 2000000000") p4 := parsePoint("cpu,host=B value=2.2 2000000000") fieldsToWrite := map[string]*tsdb.MeasurementFields{"foo": {Fields: map[string]*tsdb.Field{"bar": {Name: "value"}}}} seriesToWrite := []*tsdb.SeriesCreate{{Measurement: "asdf"}} if err := w.WritePoints([]models.Point{p1, p2}, fieldsToWrite, seriesToWrite); err != nil { t.Fatalf("failed to write points: %s", err.Error()) } fieldNames := []string{"value"} var codec *tsdb.FieldCodec c := w.Cursor("cpu,host=A", fieldNames, codec, true) k, v := c.Next() if k != p1.UnixNano() { t.Fatalf("p1 time wrong:\n\texp:%d\n\tgot:%d\n", p1.UnixNano(), k) } if 1.1 != v { t.Fatal("p1 data not equal") } c = w.Cursor("cpu,host=B", fieldNames, codec, true) k, v = c.Next() if k != p2.UnixNano() { t.Fatalf("p2 time wrong:\n\texp:%d\n\tgot:%d\n", p2.UnixNano(), k) } if 1.2 != v { t.Fatal("p2 data not equal") } k, v = c.Next() if k != tsdb.EOF { t.Fatal("expected EOF", k, v) } // ensure we can do another write to the wal and get stuff if err := w.WritePoints([]models.Point{p3}, nil, nil); err != nil { t.Fatalf("failed to write: %s", err.Error()) } c = w.Cursor("cpu,host=A", fieldNames, codec, true) k, v = c.Next() if k != p1.UnixNano() { t.Fatalf("p1 time wrong:\n\texp:%d\n\tgot:%d\n", p1.UnixNano(), k) } if 1.1 != v { t.Fatal("p1 data not equal") } k, v = c.Next() if k != p3.UnixNano() { t.Fatalf("p3 time wrong:\n\texp:%d\n\tgot:%d\n", p3.UnixNano(), k) } if 2.1 != v { t.Fatal("p3 data not equal") } // ensure we can seek k, v = c.SeekTo(2000000000) if k != p3.UnixNano() { t.Fatalf("p3 time wrong:\n\texp:%d\n\tgot:%d\n", p3.UnixNano(), k) } if 2.1 != v { t.Fatal("p3 data not equal") } k, v = c.Next() if k != tsdb.EOF { t.Fatal("expected EOF") } // ensure we close and after open it flushes to the index if err := w.Log.Close(); err != nil { t.Fatalf("failed to close: %s", err.Error()) } if err := w.Open(); err != nil { t.Fatalf("failed to open: %s", err.Error()) } if len(vals[tsm1.SeriesFieldKey("cpu,host=A", "value")]) != 2 { t.Fatal("expected host A values to flush to index on open") } if len(vals[tsm1.SeriesFieldKey("cpu,host=B", "value")]) != 1 { t.Fatal("expected host B values to flush to index on open") } if err := w.WritePoints([]models.Point{p4}, nil, nil); err != nil { t.Fatalf("failed to write: %s", err.Error()) } c = w.Cursor("cpu,host=B", fieldNames, codec, true) k, v = c.Next() if k != p4.UnixNano() { t.Fatalf("p4 time wrong:\n\texp:%d\n\tgot:%d\n", p4.UnixNano(), k) } if 2.2 != v { t.Fatal("p4 data not equal") } if !reflect.DeepEqual(fields, fieldsToWrite) { t.Fatal("fields not flushed") } if !reflect.DeepEqual(series, seriesToWrite) { t.Fatal("series not flushed") } }
func (a cursors) Less(i, j int) bool { return tsm.SeriesFieldKey(a[i].series, a[i].field) < tsm.SeriesFieldKey(a[j].series, a[j].field) }