From 81d0cb9617ab21e9236242ce7bcc4cd401b07f70 Mon Sep 17 00:00:00 2001 From: Sam Batschelet Date: Sun, 14 May 2023 11:57:56 -0400 Subject: [PATCH 1/8] add bench Signed-off-by: Sam Batschelet --- tstate/tstate_test.go | 116 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/tstate/tstate_test.go b/tstate/tstate_test.go index 4bb54919ea..7f21a6262e 100644 --- a/tstate/tstate_test.go +++ b/tstate/tstate_test.go @@ -4,6 +4,8 @@ package tstate import ( "context" + "crypto/rand" + "fmt" "testing" "github.com/ava-labs/avalanchego/database" @@ -323,3 +325,117 @@ func TestWriteChanges(t *testing.T) { require.ErrorIs(err, database.ErrNotFound, "Value not removed from db.") } } + +func BenchmarkFetchAndSetScope(b *testing.B) { + for _, size := range []int{4, 8, 16, 32, 64, 128} { + b.Run(fmt.Sprintf("fetch_and_set_scope_%d_keys", size), func(b *testing.B) { + benchmarkFetchAndSetScope(b, size) + }) + } +} + +func BenchmarkInsert(b *testing.B) { + for _, size := range []int{4, 8, 16, 32, 64, 128} { + b.Run(fmt.Sprintf("insert_%d_keys", size), func(b *testing.B) { + benchmarkInsert(b, size) + }) + } +} + + +func BenchmarkGetValue(b *testing.B) { + for _, size := range []int{4, 8, 16, 32, 64, 128} { + b.Run(fmt.Sprintf("get_%d_keys", size), func(b *testing.B) { + benchmarkGetValue(b, size) + }) + } +} + +func benchmarkFetchAndSetScope(b *testing.B, size int) { + require := require.New(b) + ts := New(size) + db := NewTestDB() + ctx := context.TODO() + + keys, vals := initializeSet(size) + for i, key := range keys { + err := db.Insert(ctx, key, vals[i]) + require.NoError(err, "Error during insert.") + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + err := ts.FetchAndSetScope(ctx, keys, db) + require.NoError(err) + } + b.ReportAllocs() + b.StopTimer() +} + +func benchmarkInsert(b *testing.B, size int) { + require := require.New(b) + ts := New(size) + ctx := context.TODO() + + keys, vals := initializeSet(size) + + storage := map[string][]byte{} + for i, key := range keys { + storage[string(key)] = vals[i] + } + + ts.SetScope(ctx, keys, storage) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + for i, key := range keys { + err := ts.Insert(ctx, key, vals[i]) + require.NoError(err, "Error during insert.") + } + } + b.ReportAllocs() + b.StopTimer() +} + +func benchmarkGetValue(b *testing.B, size int) { + require := require.New(b) + ts := New(size) + ctx := context.TODO() + + keys, vals := initializeSet(size) + + storage := map[string][]byte{} + for i, key := range keys { + storage[string(key)] = vals[i] + } + + ts.SetScope(ctx, keys, storage) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, key := range keys { + _, err := ts.GetValue(ctx, key) + require.NoError(err, "Error during insert.") + } + } + b.ReportAllocs() + b.StopTimer() +} + +func initializeSet(size int) ([][]byte, [][]byte) { + keys := [][]byte{} + vals := [][]byte{} + + for i := 0; i <= size; i++ { + keys = append(keys, randomBytes(33)) + vals = append(vals, randomBytes(8)) + } + + return keys, vals +} + +func randomBytes(size int) []byte { + bytes := make([]byte, size) + rand.Read(bytes) + return bytes +} \ No newline at end of file From 3002fd42a65acd3a0756d8a7f65f0b054f5f80f4 Mon Sep 17 00:00:00 2001 From: Sam Batschelet Date: Mon, 15 May 2023 11:15:19 -0400 Subject: [PATCH 2/8] Inline all byte to string conversions Signed-off-by: Sam Batschelet --- tstate/tstate.go | 40 ++++++++++++++++++---------------------- tstate/tstate_test.go | 3 +-- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/tstate/tstate.go b/tstate/tstate.go index 76ef7ccd7b..2d2c1ec791 100644 --- a/tstate/tstate.go +++ b/tstate/tstate.go @@ -15,7 +15,7 @@ import ( ) type op struct { - k string + k []byte pastExists bool pastV []byte @@ -67,22 +67,21 @@ func (ts *TState) GetValue(ctx context.Context, key []byte) ([]byte, error) { if !ts.checkScope(ctx, key) { return nil, ErrKeyNotSpecified } - k := string(key) - v, _, exists := ts.getValue(ctx, k) + v, _, exists := ts.getValue(ctx, key) if !exists { return nil, database.ErrNotFound } return v, nil } -func (ts *TState) getValue(_ context.Context, key string) ([]byte, bool, bool) { - if v, ok := ts.changedKeys[key]; ok { +func (ts *TState) getValue(_ context.Context, key []byte) ([]byte, bool, bool) { + if v, ok := ts.changedKeys[string(key)]; ok { if v.removed { return nil, true, false } return v.v, true, true } - v, ok := ts.scopeStorage[key] + v, ok := ts.scopeStorage[string(key)] if !ok { return nil, false, false } @@ -95,23 +94,22 @@ func (ts *TState) getValue(_ context.Context, key string) ([]byte, bool, bool) { func (ts *TState) FetchAndSetScope(ctx context.Context, keys [][]byte, db Database) error { ts.scopeStorage = map[string][]byte{} for _, key := range keys { - k := string(key) - if val, ok := ts.fetchCache[k]; ok { + if val, ok := ts.fetchCache[string(key)]; ok { if val.Exists { - ts.scopeStorage[k] = val.Value + ts.scopeStorage[string(key)] = val.Value } continue } v, err := db.GetValue(ctx, key) if errors.Is(err, database.ErrNotFound) { - ts.fetchCache[k] = &cacheItem{Exists: false} + ts.fetchCache[string(key)] = &cacheItem{Exists: false} continue } if err != nil { return err } - ts.fetchCache[k] = &cacheItem{Value: v, Exists: true} - ts.scopeStorage[k] = v + ts.fetchCache[string(key)] = &cacheItem{Value: v, Exists: true} + ts.scopeStorage[string(key)] = v } ts.scope = keys return nil @@ -139,15 +137,14 @@ func (ts *TState) Insert(ctx context.Context, key []byte, value []byte) error { if !ts.checkScope(ctx, key) { return ErrKeyNotSpecified } - k := string(key) - past, changed, exists := ts.getValue(ctx, k) + past, changed, exists := ts.getValue(ctx, key) ts.ops = append(ts.ops, &op{ - k: k, + k: key, pastExists: exists, pastV: past, pastChanged: changed, }) - ts.changedKeys[k] = &tempStorage{value, false} + ts.changedKeys[string(key)] = &tempStorage{value, false} return nil } @@ -156,18 +153,17 @@ func (ts *TState) Remove(ctx context.Context, key []byte) error { if !ts.checkScope(ctx, key) { return ErrKeyNotSpecified } - k := string(key) - past, changed, exists := ts.getValue(ctx, k) + past, changed, exists := ts.getValue(ctx, key) if !exists { return nil } ts.ops = append(ts.ops, &op{ - k: k, + k: key, pastExists: true, pastV: past, pastChanged: changed, }) - ts.changedKeys[k] = &tempStorage{nil, true} + ts.changedKeys[string(key)] = &tempStorage{nil, true} return nil } @@ -188,13 +184,13 @@ func (ts *TState) Rollback(_ context.Context, restorePoint int) { // // remove: Removed key that was modified for first time in run if !op.pastChanged { - delete(ts.changedKeys, op.k) + delete(ts.changedKeys, string(op.k)) continue } // insert: Modified key for the nth time // // remove: Removed key that was previously modified in run - ts.changedKeys[op.k] = &tempStorage{op.pastV, !op.pastExists} + ts.changedKeys[string(op.k)] = &tempStorage{op.pastV, !op.pastExists} } ts.ops = ts.ops[:restorePoint] } diff --git a/tstate/tstate_test.go b/tstate/tstate_test.go index 7f21a6262e..93000d20a0 100644 --- a/tstate/tstate_test.go +++ b/tstate/tstate_test.go @@ -342,7 +342,6 @@ func BenchmarkInsert(b *testing.B) { } } - func BenchmarkGetValue(b *testing.B) { for _, size := range []int{4, 8, 16, 32, 64, 128} { b.Run(fmt.Sprintf("get_%d_keys", size), func(b *testing.B) { @@ -438,4 +437,4 @@ func randomBytes(size int) []byte { bytes := make([]byte, size) rand.Read(bytes) return bytes -} \ No newline at end of file +} From 06ebd7f58d55c6d464c3a07b0f150fb4718fb12f Mon Sep 17 00:00:00 2001 From: Sam Batschelet Date: Mon, 15 May 2023 11:53:52 -0400 Subject: [PATCH 3/8] nits Signed-off-by: Sam Batschelet --- tstate/tstate_test.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tstate/tstate_test.go b/tstate/tstate_test.go index 93000d20a0..431133ae36 100644 --- a/tstate/tstate_test.go +++ b/tstate/tstate_test.go @@ -356,7 +356,7 @@ func benchmarkFetchAndSetScope(b *testing.B, size int) { db := NewTestDB() ctx := context.TODO() - keys, vals := initializeSet(size) + keys, vals := initializeSet(require, size) for i, key := range keys { err := db.Insert(ctx, key, vals[i]) require.NoError(err, "Error during insert.") @@ -376,7 +376,7 @@ func benchmarkInsert(b *testing.B, size int) { ts := New(size) ctx := context.TODO() - keys, vals := initializeSet(size) + keys, vals := initializeSet(require, size) storage := map[string][]byte{} for i, key := range keys { @@ -401,7 +401,7 @@ func benchmarkGetValue(b *testing.B, size int) { ts := New(size) ctx := context.TODO() - keys, vals := initializeSet(size) + keys, vals := initializeSet(require, size) storage := map[string][]byte{} for i, key := range keys { @@ -421,20 +421,21 @@ func benchmarkGetValue(b *testing.B, size int) { b.StopTimer() } -func initializeSet(size int) ([][]byte, [][]byte) { +func initializeSet(r *require.Assertions, size int) ([][]byte, [][]byte) { keys := [][]byte{} vals := [][]byte{} for i := 0; i <= size; i++ { - keys = append(keys, randomBytes(33)) - vals = append(vals, randomBytes(8)) + keys = append(keys, randomBytes(r, 65)) + vals = append(vals, randomBytes(r, 8)) } return keys, vals } -func randomBytes(size int) []byte { +func randomBytes(r *require.Assertions, size int) []byte { bytes := make([]byte, size) - rand.Read(bytes) + _, err := rand.Read(bytes) + r.NoError(err) return bytes } From e5fe915b1eef000bab9a343252c9ea69cf28ef79 Mon Sep 17 00:00:00 2001 From: Sam Batschelet Date: Mon, 15 May 2023 20:59:25 -0400 Subject: [PATCH 4/8] reduce allocations Signed-off-by: Sam Batschelet --- tstate/tstate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tstate/tstate.go b/tstate/tstate.go index 2d2c1ec791..9aa6148bc0 100644 --- a/tstate/tstate.go +++ b/tstate/tstate.go @@ -92,7 +92,7 @@ func (ts *TState) getValue(_ context.Context, key []byte) ([]byte, bool, bool) { // FetchAndSetScope then sets the scope of ts to [keys]. If a key exists in // ts.fetchCache set the key's value to the value from cache. func (ts *TState) FetchAndSetScope(ctx context.Context, keys [][]byte, db Database) error { - ts.scopeStorage = map[string][]byte{} + ts.scopeStorage = make(map[string][]byte, len(keys)) for _, key := range keys { if val, ok := ts.fetchCache[string(key)]; ok { if val.Exists { From f6877644126eaf7b7d6a369777049137fc1d15e3 Mon Sep 17 00:00:00 2001 From: Sam Batschelet Date: Wed, 17 May 2023 08:11:40 -0400 Subject: [PATCH 5/8] cleanup benchmarks Signed-off-by: Sam Batschelet --- tstate/tstate_test.go | 58 ++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/tstate/tstate_test.go b/tstate/tstate_test.go index 431133ae36..0bfd18afbd 100644 --- a/tstate/tstate_test.go +++ b/tstate/tstate_test.go @@ -327,39 +327,42 @@ func TestWriteChanges(t *testing.T) { } func BenchmarkFetchAndSetScope(b *testing.B) { + keySize := 65 for _, size := range []int{4, 8, 16, 32, 64, 128} { - b.Run(fmt.Sprintf("fetch_and_set_scope_%d_keys", size), func(b *testing.B) { - benchmarkFetchAndSetScope(b, size) + b.Run(fmt.Sprintf("fetch_and_set_scope_%d_keys_with_length_%d", size, keySize), func(b *testing.B) { + benchmarkFetchAndSetScope(b, size, keySize) }) } } func BenchmarkInsert(b *testing.B) { - for _, size := range []int{4, 8, 16, 32, 64, 128} { - b.Run(fmt.Sprintf("insert_%d_keys", size), func(b *testing.B) { - benchmarkInsert(b, size) + keySize := 65 + for _, count := range []int{4, 8, 16, 32, 64, 128} { + b.Run(fmt.Sprintf("insert_%d_keys_with_length_%d", count, keySize), func(b *testing.B) { + benchmarkInsert(b, count, keySize) }) } } func BenchmarkGetValue(b *testing.B) { - for _, size := range []int{4, 8, 16, 32, 64, 128} { - b.Run(fmt.Sprintf("get_%d_keys", size), func(b *testing.B) { - benchmarkGetValue(b, size) + keySize := 65 + for _, count := range []int{4, 8, 16, 32, 64, 128} { + b.Run(fmt.Sprintf("get_%d_keys_with_length_%d", count, keySize), func(b *testing.B) { + benchmarkGetValue(b, count, keySize) }) } } -func benchmarkFetchAndSetScope(b *testing.B, size int) { +func benchmarkFetchAndSetScope(b *testing.B, count, keySize int) { require := require.New(b) - ts := New(size) + ts := New(count) db := NewTestDB() ctx := context.TODO() - keys, vals := initializeSet(require, size) + keys, vals := initializeSet(require, count, keySize) for i, key := range keys { err := db.Insert(ctx, key, vals[i]) - require.NoError(err, "Error during insert.") + require.NoError(err, "Error during insert") } b.ResetTimer() @@ -371,65 +374,58 @@ func benchmarkFetchAndSetScope(b *testing.B, size int) { b.StopTimer() } -func benchmarkInsert(b *testing.B, size int) { +func benchmarkInsert(b *testing.B, count, keyLen int) { require := require.New(b) - ts := New(size) + ts := New(count) ctx := context.TODO() - keys, vals := initializeSet(require, size) - + keys, vals := initializeSet(require, count, keyLen) storage := map[string][]byte{} for i, key := range keys { storage[string(key)] = vals[i] } - ts.SetScope(ctx, keys, storage) b.ResetTimer() for i := 0; i < b.N; i++ { for i, key := range keys { err := ts.Insert(ctx, key, vals[i]) - require.NoError(err, "Error during insert.") + require.NoError(err, "Error during insert") } } b.ReportAllocs() b.StopTimer() } -func benchmarkGetValue(b *testing.B, size int) { +func benchmarkGetValue(b *testing.B, count, keyLen int) { require := require.New(b) - ts := New(size) + ts := New(count) ctx := context.TODO() - keys, vals := initializeSet(require, size) - + keys, vals := initializeSet(require, count, keyLen) storage := map[string][]byte{} for i, key := range keys { storage[string(key)] = vals[i] } - ts.SetScope(ctx, keys, storage) b.ResetTimer() for i := 0; i < b.N; i++ { for _, key := range keys { _, err := ts.GetValue(ctx, key) - require.NoError(err, "Error during insert.") + require.NoError(err, "Error during get") } } b.ReportAllocs() b.StopTimer() } -func initializeSet(r *require.Assertions, size int) ([][]byte, [][]byte) { - keys := [][]byte{} - vals := [][]byte{} - - for i := 0; i <= size; i++ { - keys = append(keys, randomBytes(r, 65)) +func initializeSet(r *require.Assertions, count, keyLen int) ([][]byte, [][]byte) { + var keys, vals [][]byte + for i := 0; i <= count; i++ { + keys = append(keys, randomBytes(r, keyLen)) vals = append(vals, randomBytes(r, 8)) } - return keys, vals } From 487c2b04061cf919483754c3ecc1d1bebfb250e5 Mon Sep 17 00:00:00 2001 From: Sam Batschelet Date: Wed, 17 May 2023 12:11:03 -0400 Subject: [PATCH 6/8] Fix typos Signed-off-by: Sam Batschelet --- tstate/tstate_test.go | 60 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/tstate/tstate_test.go b/tstate/tstate_test.go index 0bfd18afbd..9998c1c3e1 100644 --- a/tstate/tstate_test.go +++ b/tstate/tstate_test.go @@ -53,12 +53,12 @@ func TestGetValue(t *testing.T) { ts := New(10) // GetValue without Scope perm _, err := ts.GetValue(ctx, TestKey) - require.ErrorIs(err, ErrKeyNotSpecified, "No error thrown.") + require.ErrorIs(err, ErrKeyNotSpecified, "No error thrown") // SetScope ts.SetScope(ctx, [][]byte{TestKey}, map[string][]byte{string(TestKey): TestVal}) val, err := ts.GetValue(ctx, TestKey) require.NoError(err, "Error getting value.") - require.Equal(TestVal, val, "Value was not saved correctly.") + require.Equal(TestVal, val, "Value was not saved correctly") } func TestGetValueNoStorage(t *testing.T) { @@ -68,7 +68,7 @@ func TestGetValueNoStorage(t *testing.T) { // SetScope but dont add to storage ts.SetScope(ctx, [][]byte{TestKey}, map[string][]byte{}) _, err := ts.GetValue(ctx, TestKey) - require.ErrorIs(database.ErrNotFound, err, "No error thrown.") + require.ErrorIs(database.ErrNotFound, err, "No error thrown") } func TestInsertNew(t *testing.T) { @@ -77,16 +77,16 @@ func TestInsertNew(t *testing.T) { ts := New(10) // Insert before SetScope err := ts.Insert(ctx, TestKey, TestVal) - require.ErrorIs(ErrKeyNotSpecified, err, "No error thrown.") + require.ErrorIs(ErrKeyNotSpecified, err, "No error thrown") // SetScope ts.SetScope(ctx, [][]byte{TestKey}, map[string][]byte{}) // Insert key err = ts.Insert(ctx, TestKey, TestVal) - require.NoError(err, "Error thrown.") + require.NoError(err, "Error thrown") val, err := ts.GetValue(ctx, TestKey) - require.NoError(err, "Error thrown.") - require.Equal(1, ts.OpIndex(), "Insert operation was not added.") - require.Equal(TestVal, val, "Value was not set correctly.") + require.NoError(err, "Error thrown") + require.Equal(1, ts.OpIndex(), "Insert operation was not added") + require.Equal(TestVal, val, "Value was not set correctly") } func TestInsertUpdate(t *testing.T) { @@ -95,18 +95,18 @@ func TestInsertUpdate(t *testing.T) { ts := New(10) // SetScope and add ts.SetScope(ctx, [][]byte{TestKey}, map[string][]byte{string(TestKey): TestVal}) - require.Equal(0, ts.OpIndex(), "SetStorage operation was not added.") + require.Equal(0, ts.OpIndex(), "SetStorage operation was not added") // Insert key newVal := []byte("newVal") err := ts.Insert(ctx, TestKey, newVal) - require.NoError(err, "Error thrown.") + require.NoError(err, "Error thrown") val, err := ts.GetValue(ctx, TestKey) - require.NoError(err, "Error thrown.") + require.NoError(err, "Error thrown") require.Equal(1, ts.OpIndex(), "Insert operation was not added.") require.Equal(newVal, val, "Value was not set correctly.") - require.Equal(TestVal, ts.ops[0].pastV, "PastVal was not set correctly.") - require.False(ts.ops[0].pastChanged, "PastVal was not set correctly.") - require.True(ts.ops[0].pastExists, "PastVal was not set correctly.") + require.Equal(TestVal, ts.ops[0].pastV, "PastVal was not set correctly") + require.False(ts.ops[0].pastChanged, "PastVal was not set correctly") + require.True(ts.ops[0].pastExists, "PastVal was not set correctly") } func TestFetchAndSetScope(t *testing.T) { @@ -122,13 +122,13 @@ func TestFetchAndSetScope(t *testing.T) { } err := ts.FetchAndSetScope(ctx, keys, db) require.NoError(err, "Error thrown.") - require.Equal(0, ts.OpIndex(), "Opertions not updated correctly.") - require.Equal(keys, ts.scope, "Scope not updated correctly.") + require.Equal(0, ts.OpIndex(), "Operations not updated correctly") + require.Equal(keys, ts.scope, "Scope not updated correctly") // Check values for i, key := range keys { val, err := ts.GetValue(ctx, key) require.NoError(err, "Error getting value.") - require.Equal(vals[i], val, "Value not set correctly.") + require.Equal(vals[i], val, "Value not set correctly") } } @@ -142,20 +142,20 @@ func TestFetchAndSetScopeMissingKey(t *testing.T) { // Keys[3] not in db for i, key := range keys[:len(keys)-1] { err := db.Insert(ctx, key, vals[i]) - require.NoError(err, "Error during insert.") + require.NoError(err, "Error during insert") } err := ts.FetchAndSetScope(ctx, keys, db) require.NoError(err, "Error thrown.") - require.Equal(0, ts.OpIndex(), "Opertions not updated correctly.") - require.Equal(keys, ts.scope, "Scope not updated correctly.") + require.Equal(0, ts.OpIndex(), "Operations not updated correctly") + require.Equal(keys, ts.scope, "Scope not updated correctly") // Check values for i, key := range keys[:len(keys)-1] { val, err := ts.GetValue(ctx, key) require.NoError(err, "Error getting value.") - require.Equal(vals[i], val, "Value not set correctly.") + require.Equal(vals[i], val, "Value not set correctly") } _, err = ts.GetValue(ctx, keys[2]) - require.ErrorIs(err, database.ErrNotFound, "Didn't throw correct erro.") + require.ErrorIs(err, database.ErrNotFound, "Didn't throw correct error") } func TestSetScope(t *testing.T) { @@ -164,7 +164,7 @@ func TestSetScope(t *testing.T) { ctx := context.TODO() keys := [][]byte{[]byte("key1"), []byte("key2"), []byte("key3")} ts.SetScope(ctx, keys, map[string][]byte{}) - require.Equal(keys, ts.scope, "Scope not updated correctly.") + require.Equal(keys, ts.scope, "Scope not updated correctly") } func TestRemoveInsertRollback(t *testing.T) { @@ -174,29 +174,29 @@ func TestRemoveInsertRollback(t *testing.T) { ts.SetScope(ctx, [][]byte{TestKey}, map[string][]byte{}) // Insert err := ts.Insert(ctx, TestKey, TestVal) - require.NoError(err, "Error from insert.") + require.NoError(err, "Error from insert") v, err := ts.GetValue(ctx, TestKey) require.NoError(err) require.Equal(TestVal, v) - require.Equal(1, ts.OpIndex(), "Opertions not updated correctly.") + require.Equal(1, ts.OpIndex(), "Operations not updated correctly") // Remove err = ts.Remove(ctx, TestKey) require.NoError(err, "Error from remove.") _, err = ts.GetValue(ctx, TestKey) - require.ErrorIs(err, database.ErrNotFound, "Key not deleted from storage.") - require.Equal(2, ts.OpIndex(), "Opertions not updated correctly.") + require.ErrorIs(err, database.ErrNotFound, "Key not deleted from storage") + require.Equal(2, ts.OpIndex(), "Operations not updated correctly") // Insert err = ts.Insert(ctx, TestKey, TestVal) require.NoError(err, "Error from insert.") v, err = ts.GetValue(ctx, TestKey) require.NoError(err) require.Equal(TestVal, v) - require.Equal(3, ts.OpIndex(), "Opertions not updated correctly.") + require.Equal(3, ts.OpIndex(), "Operations not updated correctly") require.Equal(1, ts.PendingChanges()) // Rollback ts.Rollback(ctx, 2) _, err = ts.GetValue(ctx, TestKey) - require.ErrorIs(err, database.ErrNotFound, "Key not deleted from storage.") + require.ErrorIs(err, database.ErrNotFound, "Key not deleted from storage") // Rollback ts.Rollback(ctx, 1) v, err = ts.GetValue(ctx, TestKey) @@ -210,7 +210,7 @@ func TestRemoveNotInScope(t *testing.T) { ctx := context.TODO() // Remove err := ts.Remove(ctx, TestKey) - require.ErrorIs(err, ErrKeyNotSpecified, "ErrKeyNotSpecified should be thrown.") + require.ErrorIs(err, ErrKeyNotSpecified, "ErrKeyNotSpecified should be thrown") } func TestRestoreInsert(t *testing.T) { From a7628fc0700a1b7419ee545cc9b42b47b1246096 Mon Sep 17 00:00:00 2001 From: Sam Batschelet Date: Wed, 17 May 2023 13:35:47 -0400 Subject: [PATCH 7/8] Add checkScope bench Signed-off-by: Sam Batschelet --- tstate/tstate.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tstate/tstate.go b/tstate/tstate.go index 9aa6148bc0..c6632f564e 100644 --- a/tstate/tstate.go +++ b/tstate/tstate.go @@ -124,7 +124,6 @@ func (ts *TState) SetScope(_ context.Context, keys [][]byte, storage map[string] // checkScope returns whether [k] is in ts.readScope. func (ts *TState) checkScope(_ context.Context, k []byte) bool { for _, s := range ts.scope { - // TODO: benchmark and see if creating map is worth overhead if bytes.Equal(k, s) { return true } From 0c7bef58b146c10d8831e34b9bc85e188ee208a9 Mon Sep 17 00:00:00 2001 From: Sam Batschelet Date: Thu, 18 May 2023 22:01:07 -0400 Subject: [PATCH 8/8] [processor] inline all byte to string conversions Signed-off-by: Sam Batschelet --- chain/processor.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/chain/processor.go b/chain/processor.go index 0db5af72e0..e4f9f80de4 100644 --- a/chain/processor.go +++ b/chain/processor.go @@ -53,22 +53,21 @@ func (p *Processor) Prefetch(ctx context.Context, db Database) { for _, tx := range p.blk.GetTxs() { storage := map[string][]byte{} for _, k := range tx.StateKeys(sm) { - sk := string(k) - if v, ok := alreadyFetched[sk]; ok { + if v, ok := alreadyFetched[string(k)]; ok { if v.exists { - storage[sk] = v.v + storage[string(k)] = v.v } continue } v, err := db.GetValue(ctx, k) if errors.Is(err, database.ErrNotFound) { - alreadyFetched[sk] = &fetchData{nil, false} + alreadyFetched[string(k)] = &fetchData{nil, false} continue } else if err != nil { panic(err) } - alreadyFetched[sk] = &fetchData{v, true} - storage[sk] = v + alreadyFetched[string(k)] = &fetchData{v, true} + storage[string(k)] = v } p.readyTxs <- &txData{tx, storage} }