]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Benchmark different mmap sizes and journal modes
authorMatt Joiner <anacrolix@gmail.com>
Thu, 6 May 2021 02:00:20 +0000 (12:00 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 6 May 2021 02:00:20 +0000 (12:00 +1000)
storage/sqlite/direct.go
storage/sqlite/sqlite-storage.go
storage/sqlite/sqlite-storage_test.go

index 9da0f701dbc1db3e3d98b67703c76b2fb2fcabde..5f89ec9891535542292933d378866ee5e3f5096d 100644 (file)
@@ -13,6 +13,7 @@ import (
 type NewDirectStorageOpts struct {
        NewConnOpts
        InitDbOpts
+       InitConnOpts
 }
 
 // A convenience function that creates a connection pool, resource provider, and a pieces storage
@@ -22,16 +23,9 @@ func NewDirectStorage(opts NewDirectStorageOpts) (_ storage.ClientImplCloser, er
        if err != nil {
                return
        }
-       journalMode := "delete"
-       if opts.Memory {
-               journalMode = "off"
-       }
-       err = initConn(conn, InitConnOpts{
-               SetJournalMode: journalMode,
-               MmapSizeOk:     true,
-               MmapSize:       1 << 25,
-       })
+       err = initConn(conn, opts.InitConnOpts)
        if err != nil {
+               conn.Close()
                return
        }
        err = initDatabase(conn, opts.InitDbOpts)
index 8c569314e2f35180537de5f5252061821e322d34..4192a58d1232e8323ed6394fa0aaa4a898f19507 100644 (file)
@@ -38,6 +38,8 @@ func (me InitConnOpts) JournalMode() string {
        return "wal"
 }
 
+var UnexpectedJournalMode = errors.New("unexpected journal mode")
+
 func initConn(conn conn, opts InitConnOpts) error {
        // Recursive triggers are required because we need to trim the blob_meta size after trimming to
        // capacity. Hopefully we don't hit the recursion limit, and if we do, there's an error thrown.
@@ -53,7 +55,7 @@ func initConn(conn conn, opts InitConnOpts) error {
                err = sqlitex.ExecTransient(conn, fmt.Sprintf(`pragma journal_mode=%s`, opts.SetJournalMode), func(stmt *sqlite.Stmt) error {
                        ret := stmt.ColumnText(0)
                        if ret != opts.SetJournalMode {
-                               panic(ret)
+                               return UnexpectedJournalMode
                        }
                        return nil
                })
@@ -62,7 +64,10 @@ func initConn(conn conn, opts InitConnOpts) error {
                }
        }
        if !opts.MmapSizeOk {
-               opts.MmapSize = 1 << 24 // 8 MiB
+               // Set the default. Currently it seems the library picks reasonable defaults, especially for
+               // wal.
+               opts.MmapSize = -1
+               //opts.MmapSize = 1 << 24 // 8 MiB
        }
        if opts.MmapSize >= 0 {
                err = sqlitex.ExecTransient(conn, fmt.Sprintf(`pragma mmap_size=%d`, opts.MmapSize), nil)
index f2e7ad290bbe3fd0184e104335d3b022bc1a0bf8..633d4358b4ebefe2b1fbc9fe3b2ecb10395e5314 100644 (file)
@@ -2,6 +2,7 @@ package sqliteStorage
 
 import (
        "bytes"
+       "errors"
        "fmt"
        "io"
        "io/ioutil"
@@ -12,6 +13,7 @@ import (
        _ "github.com/anacrolix/envpprof"
        "github.com/anacrolix/torrent/storage"
        test_storage "github.com/anacrolix/torrent/storage/test"
+       "github.com/dustin/go-humanize"
        qt "github.com/frankban/quicktest"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
@@ -82,10 +84,36 @@ func BenchmarkMarkComplete(b *testing.B) {
                                opts.Memory = memory
                                opts.Path = filepath.Join(b.TempDir(), "storage.db")
                                opts.Capacity = capacity
-                               ci, err := NewDirectStorage(opts)
-                               c.Assert(err, qt.IsNil)
-                               defer ci.Close()
-                               runBench(b, ci)
+                               directBench := func(b *testing.B) {
+                                       ci, err := NewDirectStorage(opts)
+                                       if errors.Is(err, UnexpectedJournalMode) {
+                                               b.Skipf("setting journal mode %q: %v", opts.SetJournalMode, err)
+                                       }
+                                       c.Assert(err, qt.IsNil)
+                                       defer ci.Close()
+                                       runBench(b, ci)
+                               }
+                               for _, journalMode := range []string{"", "wal", "off", "delete", "memory"} {
+                                       opts.SetJournalMode = journalMode
+                                       b.Run("JournalMode="+journalMode, func(b *testing.B) {
+                                               for _, mmapSize := range []int64{-1, 0, 1 << 24, 1 << 25, 1 << 26} {
+                                                       if memory && mmapSize >= 0 {
+                                                               continue
+                                                       }
+                                                       b.Run(fmt.Sprintf("MmapSize=%s", func() string {
+                                                               if mmapSize < 0 {
+                                                                       return "default"
+                                                               } else {
+                                                                       return humanize.IBytes(uint64(mmapSize))
+                                                               }
+                                                       }()), func(b *testing.B) {
+                                                               opts.MmapSize = mmapSize
+                                                               opts.MmapSizeOk = true
+                                                               directBench(b)
+                                                       })
+                                               }
+                                       })
+                               }
                        })
                        b.Run("ResourcePieces", func(b *testing.B) {
                                for _, batchWrites := range []bool{false, true} {