Reduce allocations during iteration
Reuses key byte slices to reduce allocations: benchmark old allocs new allocs delta Benchmark10kReplace 178112 168615 -5.33% Benchmark10kUpdateChg 567954 561557 -1.13% Benchmark10kUpdateSme 238691 228680 -4.19% Benchmark10kNeed2k 105382 103383 -1.90% Benchmark10kHaveFullList 60230 60230 +0.00% Benchmark10kGlobal 237484 227493 -4.21% benchmark old bytes new bytes delta Benchmark10kReplace 8725368 7661788 -12.19% Benchmark10kUpdateChg 58155152 57441025 -1.23% Benchmark10kUpdateSme 16130875 14996717 -7.03% Benchmark10kNeed2k 6561685 6338283 -3.40% Benchmark10kHaveFullList 7611112 7611135 +0.00% Benchmark10kGlobal 21415056 20300723 -5.20%
This commit is contained in:
@@ -104,7 +104,14 @@ const batchFlushSize = 64
|
|||||||
// device (32 bytes)
|
// device (32 bytes)
|
||||||
// name (variable size)
|
// name (variable size)
|
||||||
func deviceKey(folder, device, file []byte) []byte {
|
func deviceKey(folder, device, file []byte) []byte {
|
||||||
k := make([]byte, 1+64+32+len(file))
|
return deviceKeyInto(nil, folder, device, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deviceKeyInto(k []byte, folder, device, file []byte) []byte {
|
||||||
|
reqLen := 1 + 64 + 32 + len(file)
|
||||||
|
if len(k) < reqLen {
|
||||||
|
k = make([]byte, reqLen)
|
||||||
|
}
|
||||||
k[0] = KeyTypeDevice
|
k[0] = KeyTypeDevice
|
||||||
if len(folder) > 64 {
|
if len(folder) > 64 {
|
||||||
panic("folder name too long")
|
panic("folder name too long")
|
||||||
@@ -112,7 +119,7 @@ func deviceKey(folder, device, file []byte) []byte {
|
|||||||
copy(k[1:], []byte(folder))
|
copy(k[1:], []byte(folder))
|
||||||
copy(k[1+64:], device[:])
|
copy(k[1+64:], device[:])
|
||||||
copy(k[1+64+32:], []byte(file))
|
copy(k[1+64+32:], []byte(file))
|
||||||
return k
|
return k[:reqLen]
|
||||||
}
|
}
|
||||||
|
|
||||||
func deviceKeyName(key []byte) []byte {
|
func deviceKeyName(key []byte) []byte {
|
||||||
@@ -370,9 +377,10 @@ func ldbUpdate(db *leveldb.DB, folder, device []byte, fs []protocol.FileInfo) in
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
var maxLocalVer int64
|
var maxLocalVer int64
|
||||||
|
var fk []byte
|
||||||
for _, f := range fs {
|
for _, f := range fs {
|
||||||
name := []byte(f.Name)
|
name := []byte(f.Name)
|
||||||
fk := deviceKey(folder, device, name)
|
fk = deviceKeyInto(fk[:cap(fk)], folder, device, name)
|
||||||
if debugDB {
|
if debugDB {
|
||||||
l.Debugf("snap.Get %p %x", snap, fk)
|
l.Debugf("snap.Get %p %x", snap, fk)
|
||||||
}
|
}
|
||||||
@@ -727,6 +735,7 @@ func ldbWithGlobal(db *leveldb.DB, folder, prefix []byte, truncate bool, fn Iter
|
|||||||
dbi := snap.NewIterator(util.BytesPrefix(globalKey(folder, prefix)), nil)
|
dbi := snap.NewIterator(util.BytesPrefix(globalKey(folder, prefix)), nil)
|
||||||
defer dbi.Release()
|
defer dbi.Release()
|
||||||
|
|
||||||
|
var fk []byte
|
||||||
for dbi.Next() {
|
for dbi.Next() {
|
||||||
var vl versionList
|
var vl versionList
|
||||||
err := vl.UnmarshalXDR(dbi.Value())
|
err := vl.UnmarshalXDR(dbi.Value())
|
||||||
@@ -738,7 +747,7 @@ func ldbWithGlobal(db *leveldb.DB, folder, prefix []byte, truncate bool, fn Iter
|
|||||||
panic("no versions?")
|
panic("no versions?")
|
||||||
}
|
}
|
||||||
name := globalKeyName(dbi.Key())
|
name := globalKeyName(dbi.Key())
|
||||||
fk := deviceKey(folder, vl.versions[0].device, name)
|
fk = deviceKeyInto(fk[:cap(fk)], folder, vl.versions[0].device, name)
|
||||||
if debugDB {
|
if debugDB {
|
||||||
l.Debugf("snap.Get %p %x", snap, fk)
|
l.Debugf("snap.Get %p %x", snap, fk)
|
||||||
}
|
}
|
||||||
@@ -815,6 +824,7 @@ func ldbWithNeed(db *leveldb.DB, folder, device []byte, truncate bool, fn Iterat
|
|||||||
dbi := snap.NewIterator(&util.Range{Start: start, Limit: limit}, nil)
|
dbi := snap.NewIterator(&util.Range{Start: start, Limit: limit}, nil)
|
||||||
defer dbi.Release()
|
defer dbi.Release()
|
||||||
|
|
||||||
|
var fk []byte
|
||||||
nextFile:
|
nextFile:
|
||||||
for dbi.Next() {
|
for dbi.Next() {
|
||||||
var vl versionList
|
var vl versionList
|
||||||
@@ -852,7 +862,7 @@ nextFile:
|
|||||||
// We haven't found a valid copy of the file with the needed version.
|
// We haven't found a valid copy of the file with the needed version.
|
||||||
continue nextFile
|
continue nextFile
|
||||||
}
|
}
|
||||||
fk := deviceKey(folder, vl.versions[i].device, name)
|
fk = deviceKeyInto(fk[:cap(fk)], folder, vl.versions[i].device, name)
|
||||||
if debugDB {
|
if debugDB {
|
||||||
l.Debugf("snap.Get %p %x", snap, fk)
|
l.Debugf("snap.Get %p %x", snap, fk)
|
||||||
}
|
}
|
||||||
@@ -1013,6 +1023,8 @@ func ldbCheckGlobals(db *leveldb.DB, folder []byte) {
|
|||||||
if debugDB {
|
if debugDB {
|
||||||
l.Debugf("new batch %p", batch)
|
l.Debugf("new batch %p", batch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fk []byte
|
||||||
for dbi.Next() {
|
for dbi.Next() {
|
||||||
gk := dbi.Key()
|
gk := dbi.Key()
|
||||||
var vl versionList
|
var vl versionList
|
||||||
@@ -1029,7 +1041,7 @@ func ldbCheckGlobals(db *leveldb.DB, folder []byte) {
|
|||||||
name := globalKeyName(gk)
|
name := globalKeyName(gk)
|
||||||
var newVL versionList
|
var newVL versionList
|
||||||
for _, version := range vl.versions {
|
for _, version := range vl.versions {
|
||||||
fk := deviceKey(folder, version.device, name)
|
fk = deviceKeyInto(fk[:cap(fk)], folder, version.device, name)
|
||||||
if debugDB {
|
if debugDB {
|
||||||
l.Debugf("snap.Get %p %x", snap, fk)
|
l.Debugf("snap.Get %p %x", snap, fk)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user