2
0
mirror of synced 2025-02-24 14:48:27 +00:00

Use BenchmarkMarkComplete for non-sqlite storages too

This commit is contained in:
Matt Joiner 2021-04-28 14:46:47 +10:00
parent 1c971078e9
commit 0021c2a70c
3 changed files with 61 additions and 19 deletions

View File

@ -0,0 +1,30 @@
package storage_test
import (
"testing"
"github.com/anacrolix/torrent/storage"
test_storage "github.com/anacrolix/torrent/storage/test"
)
func BenchmarkMarkComplete(b *testing.B) {
bench := func(b *testing.B, ci storage.ClientImpl) {
test_storage.BenchmarkPieceMarkComplete(
b, ci, test_storage.DefaultPieceSize, test_storage.DefaultNumPieces, test_storage.DefaultCapacity)
}
b.Run("File", func(b *testing.B) {
ci := storage.NewFile(b.TempDir())
b.Cleanup(func() { ci.Close() })
bench(b, ci)
})
b.Run("Mmap", func(b *testing.B) {
ci := storage.NewMMap(b.TempDir())
b.Cleanup(func() { ci.Close() })
bench(b, ci)
})
b.Run("BoltDb", func(b *testing.B) {
ci := storage.NewBoltDB(b.TempDir())
b.Cleanup(func() { ci.Close() })
bench(b, ci)
})
}

View File

@ -67,8 +67,8 @@ func TestSimultaneousIncrementalBlob(t *testing.T) {
} }
func BenchmarkMarkComplete(b *testing.B) { func BenchmarkMarkComplete(b *testing.B) {
const pieceSize = 2 << 20 const pieceSize = test_storage.DefaultPieceSize
const capacity = 0 const capacity = test_storage.DefaultCapacity
c := qt.New(b) c := qt.New(b)
for _, memory := range []bool{false, true} { for _, memory := range []bool{false, true} {
b.Run(fmt.Sprintf("Memory=%v", memory), func(b *testing.B) { b.Run(fmt.Sprintf("Memory=%v", memory), func(b *testing.B) {
@ -90,7 +90,7 @@ func BenchmarkMarkComplete(b *testing.B) {
}) })
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
defer ci.Close() defer ci.Close()
test_storage.BenchmarkPieceMarkComplete(b, ci, pieceSize, 16, capacity) test_storage.BenchmarkPieceMarkComplete(b, ci, pieceSize, test_storage.DefaultNumPieces, capacity)
}) })
} }
}) })

View File

@ -14,37 +14,47 @@ import (
qt "github.com/frankban/quicktest" qt "github.com/frankban/quicktest"
) )
const chunkSize = 1 << 14 const (
ChunkSize = 1 << 14
DefaultPieceSize = 2 << 20
DefaultCapacity = 0
DefaultNumPieces = 16
)
func BenchmarkPieceMarkComplete(b *testing.B, ci storage.ClientImpl, pieceSize int64, numPieces int, capacity int64) { func BenchmarkPieceMarkComplete(
b *testing.B, ci storage.ClientImpl,
pieceSize int64, numPieces int, capacity int64,
) {
const check = true
c := qt.New(b) c := qt.New(b)
ti, err := ci.OpenTorrent(&metainfo.Info{
Pieces: make([]byte, metainfo.HashSize*numPieces),
PieceLength: pieceSize,
}, metainfo.Hash{})
c.Assert(err, qt.IsNil)
defer ti.Close()
info := &metainfo.Info{ info := &metainfo.Info{
Pieces: make([]byte, numPieces*metainfo.HashSize), Pieces: make([]byte, numPieces*metainfo.HashSize),
PieceLength: pieceSize, PieceLength: pieceSize,
Length: pieceSize * int64(numPieces), Length: pieceSize * int64(numPieces),
Name: "TorrentName",
} }
ti, err := ci.OpenTorrent(info, metainfo.Hash{})
c.Assert(err, qt.IsNil)
defer ti.Close()
rand.Read(info.Pieces) rand.Read(info.Pieces)
data := make([]byte, pieceSize) data := make([]byte, pieceSize)
b.SetBytes(int64(numPieces) * pieceSize)
oneIter := func() { oneIter := func() {
for pieceIndex := range iter.N(numPieces) { for pieceIndex := range iter.N(numPieces) {
pi := ti.Piece(info.Piece(pieceIndex)) pi := ti.Piece(info.Piece(pieceIndex))
if check {
rand.Read(data) rand.Read(data)
}
var wg sync.WaitGroup var wg sync.WaitGroup
for off := int64(0); off < int64(len(data)); off += chunkSize { for off := int64(0); off < int64(len(data)); off += ChunkSize {
wg.Add(1) wg.Add(1)
go func(off int64) { go func(off int64) {
defer wg.Done() defer wg.Done()
n, err := pi.WriteAt(data[off:off+chunkSize], off) n, err := pi.WriteAt(data[off:off+ChunkSize], off)
if err != nil { if err != nil {
panic(err) panic(err)
} }
if n != chunkSize { if n != ChunkSize {
panic(n) panic(n)
} }
}(off) }(off)
@ -57,12 +67,14 @@ func BenchmarkPieceMarkComplete(b *testing.B, ci storage.ClientImpl, pieceSize i
c.Assert(pi.Completion(), qt.Equals, storage.Completion{Complete: false, Ok: true}) c.Assert(pi.Completion(), qt.Equals, storage.Completion{Complete: false, Ok: true})
c.Assert(pi.MarkComplete(), qt.IsNil) c.Assert(pi.MarkComplete(), qt.IsNil)
c.Assert(pi.Completion(), qt.Equals, storage.Completion{true, true}) c.Assert(pi.Completion(), qt.Equals, storage.Completion{true, true})
if check {
readData, err := ioutil.ReadAll(io.NewSectionReader(pi, 0, int64(len(data)))) readData, err := ioutil.ReadAll(io.NewSectionReader(pi, 0, int64(len(data))))
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
c.Assert(len(readData), qt.Equals, len(data)) c.Assert(len(readData), qt.Equals, len(data))
c.Assert(bytes.Equal(readData, data), qt.IsTrue) c.Assert(bytes.Equal(readData, data), qt.IsTrue)
} }
} }
}
// Fill the cache // Fill the cache
if capacity > 0 { if capacity > 0 {
for range iter.N(int((capacity + info.TotalLength() - 1) / info.TotalLength())) { for range iter.N(int((capacity + info.TotalLength() - 1) / info.TotalLength())) {