lib/db: Switch to faster blobloom Bloom filter pkg (#6537)

This commit is contained in:
greatroar
2020-04-20 09:02:33 +02:00
committed by GitHub
parent 4aa2199d5b
commit 44b0f0b456
3 changed files with 21 additions and 19 deletions
+16 -5
View File
@@ -12,12 +12,12 @@ import (
"encoding/binary"
"time"
"github.com/greatroar/blobloom"
"github.com/syncthing/syncthing/lib/db/backend"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/sync"
"github.com/syncthing/syncthing/lib/util"
"github.com/thejerf/suture"
"github.com/willf/bloom"
)
const (
@@ -27,7 +27,8 @@ const (
// than 100k. For fewer than 100k items we will just get better false
// positive rate instead.
indirectGCBloomCapacity = 100000
indirectGCBloomFalsePositiveRate = 0.01 // 1%
indirectGCBloomFalsePositiveRate = 0.01 // 1%
indirectGCBloomMaxBytes = 32 << 20 // Use at most 32MiB memory, which covers our desired FP rate at 27 M items
indirectGCDefaultInterval = 13 * time.Hour
indirectGCTimeKey = "lastIndirectGCTime"
@@ -595,7 +596,11 @@ func (db *Lowlevel) gcIndirect(ctx context.Context) error {
if db.gcKeyCount > capacity {
capacity = db.gcKeyCount
}
blockFilter := bloom.NewWithEstimates(uint(capacity), indirectGCBloomFalsePositiveRate)
blockFilter := blobloom.NewOptimized(blobloom.Config{
FPRate: indirectGCBloomFalsePositiveRate,
MaxBits: 8 * indirectGCBloomMaxBytes,
NKeys: uint64(capacity),
})
// Iterate the FileInfos, unmarshal the block and version hashes and
// add them to the filter.
@@ -617,7 +622,7 @@ func (db *Lowlevel) gcIndirect(ctx context.Context) error {
return err
}
if len(bl.BlocksHash) > 0 {
blockFilter.Add(bl.BlocksHash)
blockFilter.Add64(bloomHash(bl.BlocksHash))
}
}
it.Release()
@@ -642,7 +647,7 @@ func (db *Lowlevel) gcIndirect(ctx context.Context) error {
}
key := blockListKey(it.Key())
if blockFilter.Test(key.BlocksHash()) {
if blockFilter.Has64(bloomHash(key)) {
matchedBlocks++
continue
}
@@ -665,6 +670,12 @@ func (db *Lowlevel) gcIndirect(ctx context.Context) error {
return db.Compact()
}
// Hash function for the bloomfilter: first eight bytes of the SHA-256.
// Big or little-endian makes no difference, as long as we're consistent.
func bloomHash(key blockListKey) uint64 {
return binary.BigEndian.Uint64(key.BlocksHash())
}
// CheckRepair checks folder metadata and sequences for miscellaneous errors.
func (db *Lowlevel) CheckRepair() {
for _, folder := range db.ListFolders() {