2015-10-21 15:00:09 +00:00
|
|
|
// Copyright (C) 2015 The Syncthing Authors.
|
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
2017-02-09 06:52:18 +00:00
|
|
|
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
2015-10-21 15:00:09 +00:00
|
|
|
|
|
|
|
package db_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/syncthing/syncthing/lib/db"
|
2019-11-29 08:11:52 +00:00
|
|
|
"github.com/syncthing/syncthing/lib/db/backend"
|
2018-01-28 11:26:01 +00:00
|
|
|
"github.com/syncthing/syncthing/lib/fs"
|
2015-10-21 15:00:09 +00:00
|
|
|
"github.com/syncthing/syncthing/lib/protocol"
|
|
|
|
)
|
|
|
|
|
2020-05-11 13:07:06 +00:00
|
|
|
var files, filesUpdated, oneFile, firstHalf, secondHalf, changed100, unchanged100 []protocol.FileInfo
|
2018-05-17 07:26:40 +00:00
|
|
|
|
2019-07-28 20:31:25 +00:00
|
|
|
func lazyInitBenchFiles() {
|
|
|
|
if files != nil {
|
2018-05-17 07:26:40 +00:00
|
|
|
return
|
|
|
|
}
|
2015-10-21 15:00:09 +00:00
|
|
|
|
2019-07-28 20:31:25 +00:00
|
|
|
files = make([]protocol.FileInfo, 0, 1000)
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < 1000; i++ {
|
|
|
|
files = append(files, protocol.FileInfo{
|
|
|
|
Name: fmt.Sprintf("file%d", i),
|
2018-12-18 11:36:38 +00:00
|
|
|
Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}},
|
2015-10-21 15:00:09 +00:00
|
|
|
Blocks: genBlocks(i),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
middle := len(files) / 2
|
|
|
|
firstHalf = files[:middle]
|
|
|
|
secondHalf = files[middle:]
|
|
|
|
oneFile = firstHalf[middle-1 : middle]
|
2020-05-11 13:07:06 +00:00
|
|
|
|
|
|
|
unchanged100 := files[100:200]
|
|
|
|
changed100 := append([]protocol.FileInfo{}, unchanged100...)
|
|
|
|
for i := range changed100 {
|
|
|
|
changed100[i].Version = changed100[i].Version.Copy().Update(myID)
|
|
|
|
}
|
2019-07-28 20:31:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func getBenchFileSet() (*db.Lowlevel, *db.FileSet) {
|
|
|
|
lazyInitBenchFiles()
|
2015-10-21 15:00:09 +00:00
|
|
|
|
2019-11-29 08:11:52 +00:00
|
|
|
ldb := db.NewLowlevel(backend.OpenMemory())
|
2019-07-28 20:31:25 +00:00
|
|
|
benchS := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
2018-05-17 07:26:40 +00:00
|
|
|
replace(benchS, remoteDevice0, files)
|
|
|
|
replace(benchS, protocol.LocalDeviceID, firstHalf)
|
2019-07-28 20:31:25 +00:00
|
|
|
|
|
|
|
return ldb, benchS
|
2015-10-21 15:00:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkReplaceAll(b *testing.B) {
|
2019-11-29 08:11:52 +00:00
|
|
|
ldb := db.NewLowlevel(backend.OpenMemory())
|
2019-01-19 19:24:44 +00:00
|
|
|
defer ldb.Close()
|
2015-10-21 15:00:09 +00:00
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
2018-01-28 11:26:01 +00:00
|
|
|
m := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
|
|
|
replace(m, protocol.LocalDeviceID, files)
|
2015-10-21 15:00:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkUpdateOneChanged(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2018-05-17 07:26:40 +00:00
|
|
|
|
2015-10-21 15:00:09 +00:00
|
|
|
changed := make([]protocol.FileInfo, 1)
|
|
|
|
changed[0] = oneFile[0]
|
2019-01-19 19:24:44 +00:00
|
|
|
changed[0].Version = changed[0].Version.Copy().Update(myID)
|
2015-10-21 15:00:09 +00:00
|
|
|
|
2018-05-17 07:26:40 +00:00
|
|
|
b.ResetTimer()
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
2019-01-19 19:24:44 +00:00
|
|
|
if i%2 == 0 {
|
2018-05-17 07:26:40 +00:00
|
|
|
benchS.Update(protocol.LocalDeviceID, changed)
|
2015-10-21 15:00:09 +00:00
|
|
|
} else {
|
2018-05-17 07:26:40 +00:00
|
|
|
benchS.Update(protocol.LocalDeviceID, oneFile)
|
2015-10-21 15:00:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
2019-01-19 19:24:44 +00:00
|
|
|
func BenchmarkUpdate100Changed(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2019-01-19 19:24:44 +00:00
|
|
|
|
2020-05-11 13:07:06 +00:00
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if i%2 == 0 {
|
|
|
|
benchS.Update(protocol.LocalDeviceID, changed100)
|
|
|
|
} else {
|
|
|
|
benchS.Update(protocol.LocalDeviceID, unchanged100)
|
|
|
|
}
|
2019-01-19 19:24:44 +00:00
|
|
|
}
|
|
|
|
|
2020-05-11 13:07:06 +00:00
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func setup10Remotes(benchS *db.FileSet) {
|
|
|
|
idBase := remoteDevice1.String()[1:]
|
|
|
|
first := 'J'
|
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
id, _ := protocol.DeviceIDFromString(fmt.Sprintf("%v%s", first+rune(i), idBase))
|
|
|
|
if i%2 == 0 {
|
|
|
|
benchS.Update(id, changed100)
|
|
|
|
} else {
|
|
|
|
benchS.Update(id, unchanged100)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkUpdate100Changed10Remotes(b *testing.B) {
|
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
|
|
|
|
|
|
|
setup10Remotes(benchS)
|
|
|
|
|
2019-01-19 19:24:44 +00:00
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if i%2 == 0 {
|
2020-05-11 13:07:06 +00:00
|
|
|
benchS.Update(protocol.LocalDeviceID, changed100)
|
2019-01-19 19:24:44 +00:00
|
|
|
} else {
|
2020-05-11 13:07:06 +00:00
|
|
|
benchS.Update(protocol.LocalDeviceID, unchanged100)
|
2019-01-19 19:24:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkUpdate100ChangedRemote(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2019-01-19 19:24:44 +00:00
|
|
|
|
2020-05-11 13:07:06 +00:00
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if i%2 == 0 {
|
|
|
|
benchS.Update(remoteDevice0, changed100)
|
|
|
|
} else {
|
|
|
|
benchS.Update(remoteDevice0, unchanged100)
|
|
|
|
}
|
2019-01-19 19:24:44 +00:00
|
|
|
}
|
|
|
|
|
2020-05-11 13:07:06 +00:00
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkUpdate100ChangedRemote10Remotes(b *testing.B) {
|
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
|
|
|
|
2019-01-19 19:24:44 +00:00
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if i%2 == 0 {
|
2020-05-11 13:07:06 +00:00
|
|
|
benchS.Update(remoteDevice0, changed100)
|
2019-01-19 19:24:44 +00:00
|
|
|
} else {
|
2020-05-11 13:07:06 +00:00
|
|
|
benchS.Update(remoteDevice0, unchanged100)
|
2019-01-19 19:24:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
2015-10-21 15:00:09 +00:00
|
|
|
func BenchmarkUpdateOneUnchanged(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2018-05-17 07:26:40 +00:00
|
|
|
|
|
|
|
b.ResetTimer()
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
2018-05-17 07:26:40 +00:00
|
|
|
benchS.Update(protocol.LocalDeviceID, oneFile)
|
2015-10-21 15:00:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkNeedHalf(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2018-05-17 07:26:40 +00:00
|
|
|
|
|
|
|
b.ResetTimer()
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
count := 0
|
2020-01-21 17:23:08 +00:00
|
|
|
snap := benchS.Snapshot()
|
|
|
|
snap.WithNeed(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
2015-10-21 15:00:09 +00:00
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
2020-01-21 17:23:08 +00:00
|
|
|
snap.Release()
|
2015-10-21 15:00:09 +00:00
|
|
|
if count != len(secondHalf) {
|
|
|
|
b.Errorf("wrong length %d != %d", count, len(secondHalf))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
2019-01-19 19:24:44 +00:00
|
|
|
func BenchmarkNeedHalfRemote(b *testing.B) {
|
2019-11-29 08:11:52 +00:00
|
|
|
ldb := db.NewLowlevel(backend.OpenMemory())
|
2019-01-19 19:24:44 +00:00
|
|
|
defer ldb.Close()
|
|
|
|
fset := db.NewFileSet("test)", fs.NewFilesystem(fs.FilesystemTypeBasic, "."), ldb)
|
|
|
|
replace(fset, remoteDevice0, firstHalf)
|
|
|
|
replace(fset, protocol.LocalDeviceID, files)
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
count := 0
|
2020-01-21 17:23:08 +00:00
|
|
|
snap := fset.Snapshot()
|
|
|
|
snap.WithNeed(remoteDevice0, func(fi db.FileIntf) bool {
|
2019-01-19 19:24:44 +00:00
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
2020-01-21 17:23:08 +00:00
|
|
|
snap.Release()
|
2019-01-19 19:24:44 +00:00
|
|
|
if count != len(secondHalf) {
|
|
|
|
b.Errorf("wrong length %d != %d", count, len(secondHalf))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
2015-10-21 15:00:09 +00:00
|
|
|
func BenchmarkHave(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2018-05-17 07:26:40 +00:00
|
|
|
|
|
|
|
b.ResetTimer()
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
count := 0
|
2020-01-21 17:23:08 +00:00
|
|
|
snap := benchS.Snapshot()
|
|
|
|
snap.WithHave(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
2015-10-21 15:00:09 +00:00
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
2020-01-21 17:23:08 +00:00
|
|
|
snap.Release()
|
2015-10-21 15:00:09 +00:00
|
|
|
if count != len(firstHalf) {
|
|
|
|
b.Errorf("wrong length %d != %d", count, len(firstHalf))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkGlobal(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2018-05-17 07:26:40 +00:00
|
|
|
|
|
|
|
b.ResetTimer()
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
count := 0
|
2020-01-21 17:23:08 +00:00
|
|
|
snap := benchS.Snapshot()
|
|
|
|
snap.WithGlobal(func(fi db.FileIntf) bool {
|
2015-10-21 15:00:09 +00:00
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
2020-01-21 17:23:08 +00:00
|
|
|
snap.Release()
|
2015-10-21 15:00:09 +00:00
|
|
|
if count != len(files) {
|
|
|
|
b.Errorf("wrong length %d != %d", count, len(files))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkNeedHalfTruncated(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2018-05-17 07:26:40 +00:00
|
|
|
|
|
|
|
b.ResetTimer()
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
count := 0
|
2020-01-21 17:23:08 +00:00
|
|
|
snap := benchS.Snapshot()
|
|
|
|
snap.WithNeedTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
2015-10-21 15:00:09 +00:00
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
2020-01-21 17:23:08 +00:00
|
|
|
snap.Release()
|
2015-10-21 15:00:09 +00:00
|
|
|
if count != len(secondHalf) {
|
|
|
|
b.Errorf("wrong length %d != %d", count, len(secondHalf))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkHaveTruncated(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2018-05-17 07:26:40 +00:00
|
|
|
|
|
|
|
b.ResetTimer()
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
count := 0
|
2020-01-21 17:23:08 +00:00
|
|
|
snap := benchS.Snapshot()
|
|
|
|
snap.WithHaveTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
2015-10-21 15:00:09 +00:00
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
2020-01-21 17:23:08 +00:00
|
|
|
snap.Release()
|
2015-10-21 15:00:09 +00:00
|
|
|
if count != len(firstHalf) {
|
|
|
|
b.Errorf("wrong length %d != %d", count, len(firstHalf))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkGlobalTruncated(b *testing.B) {
|
2019-07-28 20:31:25 +00:00
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
2018-05-17 07:26:40 +00:00
|
|
|
|
|
|
|
b.ResetTimer()
|
2015-10-21 15:00:09 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
count := 0
|
2020-01-21 17:23:08 +00:00
|
|
|
snap := benchS.Snapshot()
|
|
|
|
snap.WithGlobalTruncated(func(fi db.FileIntf) bool {
|
2015-10-21 15:00:09 +00:00
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
2020-01-21 17:23:08 +00:00
|
|
|
snap.Release()
|
2015-10-21 15:00:09 +00:00
|
|
|
if count != len(files) {
|
|
|
|
b.Errorf("wrong length %d != %d", count, len(files))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|
2020-05-11 13:07:06 +00:00
|
|
|
|
|
|
|
func BenchmarkNeedCount(b *testing.B) {
|
|
|
|
ldb, benchS := getBenchFileSet()
|
|
|
|
defer ldb.Close()
|
|
|
|
|
|
|
|
benchS.Update(protocol.LocalDeviceID, changed100)
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
snap := benchS.Snapshot()
|
|
|
|
_ = snap.NeedSize(protocol.LocalDeviceID)
|
|
|
|
snap.Release()
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
}
|