Skip to content

Commit

Permalink
add bench test
Browse files Browse the repository at this point in the history
  • Loading branch information
kbabushkin committed Mar 15, 2024
1 parent fcb5281 commit 8e472ce
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 36 deletions.
8 changes: 4 additions & 4 deletions pkg/storage/buntdb/buntdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,8 @@ func (s *Storage) GetChunks(ctx context.Context, logID string) ([]logfs.ChunkInf
tx := mustBeginTx(s.db, false)
defer mustRollback(tx)

if _, err := tx.Get(logKey(logID)); err != nil && errors.Is(err, buntdb.ErrNotFound) {
return nil, fmt.Errorf("log(ID=%s) does not exists: %w", logID, errors.ErrNotExist)
if _, err := s.getLogEntry(tx, logKey(logID), true); err != nil {
return nil, fmt.Errorf("getLogEntry(ID=%s) failed: %w", logID, err)
}

return getLogChunks(ctx, tx, logID)
Expand All @@ -442,8 +442,8 @@ func (s *Storage) UpsertChunkInfos(ctx context.Context, logID string, cis []logf
tx := mustBeginTx(s.db, true)
defer mustRollback(tx)

if _, err := tx.Get(logKey(logID)); err != nil && errors.Is(err, buntdb.ErrNotFound) {
return fmt.Errorf("log(ID=%s) does not exists: %w", logID, errors.ErrNotExist)
if _, err := s.getLogEntry(tx, logKey(logID), true); err != nil {
return fmt.Errorf("getLogEntry(ID=%s) failed: %w", logID, err)
}

for _, chnk := range cis {
Expand Down
167 changes: 135 additions & 32 deletions pkg/storage/buntdb/buntdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@ package buntdb

import (
"context"
"fmt"
"github.com/solarisdb/solaris/api/gen/solaris/v1"
"github.com/solarisdb/solaris/golibs/errors"
"github.com/solarisdb/solaris/pkg/storage"
"github.com/solarisdb/solaris/pkg/storage/logfs"
"github.com/stretchr/testify/assert"
"maps"
"math/rand"
"testing"
)

func TestStorage_CreateLog(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log := &solaris.Log{Tags: map[string]string{"tag1": "val1", "tag2": "val2"}}
log, err := s.CreateLog(ctx, log)
log, err = s.CreateLog(ctx, log)
assert.Nil(t, err)
assert.NotEmpty(t, log.ID)
assert.NotEmpty(t, log.CreatedAt)
Expand All @@ -25,10 +28,11 @@ func TestStorage_CreateLog(t *testing.T) {

func TestStorage_UpdateLog(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log1 := &solaris.Log{Tags: map[string]string{"tag1": "val1", "tag2": "val2"}}
log1, err := s.CreateLog(ctx, log1)
log1, err = s.CreateLog(ctx, log1)
assert.Nil(t, err)

log2, err := s.GetLogByID(ctx, log1.ID)
Expand All @@ -44,10 +48,11 @@ func TestStorage_UpdateLog(t *testing.T) {

func TestStorage_GetLogByID(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log1 := &solaris.Log{Tags: map[string]string{"tag1": "val1", "tag2": "val2"}}
log1, err := s.CreateLog(ctx, log1)
log1, err = s.CreateLog(ctx, log1)
assert.Nil(t, err)

log2 := &solaris.Log{Tags: map[string]string{"tag3": "val3", "tag4": "val4"}}
Expand All @@ -67,10 +72,11 @@ func TestStorage_GetLogByID(t *testing.T) {

func TestStorage_QueryLogsByCondition(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log1 := &solaris.Log{Tags: map[string]string{"tag1": "val1", "tag2": "val2"}}
log1, err := s.CreateLog(ctx, log1)
log1, err = s.CreateLog(ctx, log1)
assert.Nil(t, err)

log2 := &solaris.Log{Tags: map[string]string{"tag3": "val3", "tag4": "val4"}}
Expand All @@ -90,10 +96,11 @@ func TestStorage_QueryLogsByCondition(t *testing.T) {

func TestStorage_QueryLogsByIDs(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log1 := &solaris.Log{}
log1, err := s.CreateLog(ctx, log1)
log1, err = s.CreateLog(ctx, log1)
assert.Nil(t, err)

log2 := &solaris.Log{}
Expand All @@ -113,10 +120,11 @@ func TestStorage_QueryLogsByIDs(t *testing.T) {

func TestStorage_DeleteLogsByCondition(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log1 := &solaris.Log{Tags: map[string]string{"tag1": "val1", "tag2": "val2"}}
log1, err := s.CreateLog(ctx, log1)
log1, err = s.CreateLog(ctx, log1)
assert.Nil(t, err)

log2 := &solaris.Log{Tags: map[string]string{"tag3": "val3", "tag4": "val4"}}
Expand All @@ -135,10 +143,11 @@ func TestStorage_DeleteLogsByCondition(t *testing.T) {

func TestStorage_DeleteLogsByConditionMarkOnly(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log := &solaris.Log{Tags: map[string]string{"tag1": "val1", "tag2": "val2"}}
log, err := s.CreateLog(ctx, log)
log, err = s.CreateLog(ctx, log)
assert.Nil(t, err)

dr, err := s.DeleteLogs(ctx, storage.DeleteLogsRequest{Condition: "tag('tag1') = 'val1'", MarkOnly: true})
Expand All @@ -163,10 +172,11 @@ func TestStorage_DeleteLogsByConditionMarkOnly(t *testing.T) {

func TestStorage_DeleteLogsByIDs(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log1 := &solaris.Log{Tags: map[string]string{"tag1": "val1", "tag2": "val2"}}
log1, err := s.CreateLog(ctx, log1)
log1, err = s.CreateLog(ctx, log1)
assert.Nil(t, err)

log2 := &solaris.Log{Tags: map[string]string{"tag3": "val3", "tag4": "val4"}}
Expand All @@ -184,10 +194,11 @@ func TestStorage_DeleteLogsByIDs(t *testing.T) {

func TestStorage_DeleteLogByIDsWithChunks(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log1 := &solaris.Log{}
log1, err := s.CreateLog(ctx, log1)
log1, err = s.CreateLog(ctx, log1)
assert.Nil(t, err)

cis1 := []logfs.ChunkInfo{{ID: "2"}, {ID: "1"}}
Expand Down Expand Up @@ -224,9 +235,10 @@ func TestStorage_DeleteLogByIDsWithChunks(t *testing.T) {

func TestStorage_GetLastChunk(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

_, err := s.GetLastChunk(ctx, "noID")
_, err = s.GetLastChunk(ctx, "noID")
assert.ErrorIs(t, err, errors.ErrNotExist)

log := &solaris.Log{}
Expand All @@ -247,10 +259,11 @@ func TestStorage_GetLastChunk(t *testing.T) {

func TestStorage_GetChunks(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log := &solaris.Log{}
log, err := s.CreateLog(ctx, log)
log, err = s.CreateLog(ctx, log)
assert.Nil(t, err)

cis1 := []logfs.ChunkInfo{{ID: "2"}, {ID: "1"}}
Expand All @@ -264,9 +277,10 @@ func TestStorage_GetChunks(t *testing.T) {

func TestStorage_UpsertChunkInfos(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

_, err := s.GetChunks(ctx, "noID")
_, err = s.GetChunks(ctx, "noID")
assert.ErrorIs(t, err, errors.ErrNotExist)

log := &solaris.Log{}
Expand All @@ -292,10 +306,11 @@ func TestStorage_UpsertChunkInfos(t *testing.T) {

func TestStorage_DeleteLogChunks(t *testing.T) {
ctx := context.Background()
s := getStorage(ctx, t)
s, err := getStorage(ctx)
assert.Nil(t, err)

log1 := &solaris.Log{}
log1, err := s.CreateLog(ctx, log1)
log1, err = s.CreateLog(ctx, log1)
assert.Nil(t, err)

cis1 := []logfs.ChunkInfo{{ID: "2"}, {ID: "1"}}
Expand All @@ -315,13 +330,101 @@ func TestStorage_DeleteLogChunks(t *testing.T) {
assert.Equal(t, int64(1), cnt.Total)
}

func getStorage(ctx context.Context, t *testing.T) *Storage {
func BenchmarkCache_GetLastChunk(b *testing.B) {
ctx := context.Background()
s, _ := getStorage(ctx)

const (
numLogs = 1000
numChnksPerLog = 1000
)

var logIDs []string
for i := 0; i < numLogs; i++ {
log, err := s.CreateLog(ctx, &solaris.Log{})
if err != nil {
b.Fatal(err)
}
logIDs = append(logIDs, log.ID)
var cis []logfs.ChunkInfo
for j := 0; j < numChnksPerLog; j++ {
cis = append(cis, logfs.ChunkInfo{ID: fmt.Sprintf("%d", j)})
}
err = s.UpsertChunkInfos(ctx, log.ID, cis)
if err != nil {
b.Fatal(err)
}
}

b.ResetTimer()
b.ReportAllocs()

empty := logfs.ChunkInfo{}
for i := 0; i < b.N; i++ {
logID := logIDs[rand.Intn(len(logIDs))]
lc, err := s.GetLastChunk(ctx, logID)
if err != nil {
b.Fatal(err)
}
if lc == empty {
b.Fatalf("no last chunk")
}
}
}

func BenchmarkCache_GetChunks(b *testing.B) {
ctx := context.Background()
s, _ := getStorage(ctx)

const (
numLogs = 1000
numChnksPerLog = 1000
)

var logIDs []string
for i := 0; i < numLogs; i++ {
log, err := s.CreateLog(ctx, &solaris.Log{})
if err != nil {
b.Fatal(err)
}
logIDs = append(logIDs, log.ID)
var cis []logfs.ChunkInfo
for j := 0; j < numChnksPerLog; j++ {
cis = append(cis, logfs.ChunkInfo{ID: fmt.Sprintf("%d", j)})
}
err = s.UpsertChunkInfos(ctx, log.ID, cis)
if err != nil {
b.Fatal(err)
}
}

b.ResetTimer()
b.ReportAllocs()

for i := 0; i < b.N; i++ {
logID := logIDs[rand.Intn(len(logIDs))]
cis, err := s.GetChunks(ctx, logID)
if err != nil {
b.Fatal(err)
}
if len(cis) != numChnksPerLog {
b.Fatalf("%d != %d", len(cis), numChnksPerLog)
}
}
}

func getStorage(ctx context.Context) (*Storage, error) {
//s := NewStorage(Config{DBFilePath: "/tmp/solaris_test.db"})
s := NewStorage(Config{DBFilePath: ""})
assert.Nil(t, s.Init(ctx))

if err := s.Init(ctx); err != nil {
return nil, err
}
tx := mustBeginTx(s.db, true)
assert.Nil(t, tx.DeleteAll())
assert.Nil(t, tx.Commit())
return s
if err := tx.DeleteAll(); err != nil {
return nil, err
}
if err := tx.Commit(); err != nil {
return nil, err
}
return s, nil
}

0 comments on commit 8e472ce

Please sign in to comment.