Skip to content

Commit

Permalink
Fix bug with bz1 where some data would get hidden.
Browse files Browse the repository at this point in the history
Seeking to the middle of a compressed block wasn't working properly. Fixes influxdata#3781
  • Loading branch information
pauldix committed Aug 25, 2015
1 parent 1ed64aa commit ad3c400
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
13 changes: 12 additions & 1 deletion tsdb/engine/bz1/bz1.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type WAL interface {
Cursor(key string) tsdb.Cursor
Open() error
Close() error
Flush() error
}

// NewEngine returns a new instance of Engine.
Expand Down Expand Up @@ -613,7 +614,17 @@ type Cursor struct {
// Seek moves the cursor to a position and returns the closest key/value pair.
func (c *Cursor) Seek(seek []byte) (key, value []byte) {
// Move cursor to appropriate block and set to buffer.
_, v := c.cursor.Seek(seek)
k, v := c.cursor.Seek(seek)
if v == nil { // get the last block, it might have this time
_, v = c.cursor.Last()
} else if bytes.Compare(seek, k) == -1 { // the seek key is less than this block, go back one and check
_, v = c.cursor.Prev()

// if the previous block max time is less than the seek value, reset to where we were originally
if v == nil || bytes.Compare(seek, v[0:8]) > 0 {
_, v = c.cursor.Seek(seek)
}
}
c.setBuf(v)

// Read current block up to seek position.
Expand Down
37 changes: 37 additions & 0 deletions tsdb/engine/bz1/bz1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,41 @@ func TestEngine_WriteIndex_Insert(t *testing.T) {
}
}

// Ensure that the engine properly seeks to a block when the seek value is in the middle.
func TestEngine_WriteIndex_SeekAgainstInBlockValue(t *testing.T) {
e := OpenDefaultEngine()
defer e.Close()

// make sure we have data split across two blocks
dataSize := (bz1.DefaultBlockSize - 16) / 2
data := make([]byte, dataSize, dataSize)
// Write initial points to index.
if err := e.WriteIndex(map[string][][]byte{
"cpu": [][]byte{
append(u64tob(10), data...),
append(u64tob(20), data...),
append(u64tob(30), data...),
append(u64tob(40), data...),
},
}, nil, nil); err != nil {
t.Fatal(err)
}

// Start transaction.
tx := e.MustBegin(false)
defer tx.Rollback()

// Ensure that we can seek to a block in the middle
c := tx.Cursor("cpu")
if k, _ := c.Seek(u64tob(15)); btou64(k) != 20 {
t.Fatalf("expected to seek to time 20, but got %d", btou64(k))
}
// Ensure that we can seek to the block on the end
if k, _ := c.Seek(u64tob(35)); btou64(k) != 40 {
t.Fatalf("expected to seek to time 40, but got %d", btou64(k))
}
}

// Ensure the engine ignores writes without keys.
func TestEngine_WriteIndex_NoKeys(t *testing.T) {
e := OpenDefaultEngine()
Expand Down Expand Up @@ -479,6 +514,8 @@ func (w *EnginePointsWriter) Close() error { return nil }

func (w *EnginePointsWriter) Cursor(key string) tsdb.Cursor { return &Cursor{} }

func (w *EnginePointsWriter) Flush() error { return nil }

// Cursor represents a mock that implements tsdb.Curosr.
type Cursor struct {
}
Expand Down

0 comments on commit ad3c400

Please sign in to comment.