mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
vendor: introduces leveldb pick compaction optimization
This commit is contained in:
parent
7504dbd6eb
commit
228f080ebd
2 changed files with 72 additions and 9 deletions
4
vendor/github.com/syndtr/goleveldb/leveldb/session_compaction.go
generated
vendored
4
vendor/github.com/syndtr/goleveldb/leveldb/session_compaction.go
generated
vendored
|
|
@ -181,11 +181,15 @@ func (c *compaction) expand() {
|
||||||
|
|
||||||
t0, t1 := c.levels[0], c.levels[1]
|
t0, t1 := c.levels[0], c.levels[1]
|
||||||
imin, imax := t0.getRange(c.s.icmp)
|
imin, imax := t0.getRange(c.s.icmp)
|
||||||
|
|
||||||
|
// For non-zero levels, the ukey can't hop across tables at all.
|
||||||
|
if c.sourceLevel == 0 {
|
||||||
// We expand t0 here just incase ukey hop across tables.
|
// We expand t0 here just incase ukey hop across tables.
|
||||||
t0 = vt0.getOverlaps(t0, c.s.icmp, imin.ukey(), imax.ukey(), c.sourceLevel == 0)
|
t0 = vt0.getOverlaps(t0, c.s.icmp, imin.ukey(), imax.ukey(), c.sourceLevel == 0)
|
||||||
if len(t0) != len(c.levels[0]) {
|
if len(t0) != len(c.levels[0]) {
|
||||||
imin, imax = t0.getRange(c.s.icmp)
|
imin, imax = t0.getRange(c.s.icmp)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
t1 = vt1.getOverlaps(t1, c.s.icmp, imin.ukey(), imax.ukey(), false)
|
t1 = vt1.getOverlaps(t1, c.s.icmp, imin.ukey(), imax.ukey(), false)
|
||||||
// Get entire range covered by compaction.
|
// Get entire range covered by compaction.
|
||||||
amin, amax := append(t0, t1...).getRange(c.s.icmp)
|
amin, amax := append(t0, t1...).getRange(c.s.icmp)
|
||||||
|
|
|
||||||
63
vendor/github.com/syndtr/goleveldb/leveldb/table.go
generated
vendored
63
vendor/github.com/syndtr/goleveldb/leveldb/table.go
generated
vendored
|
|
@ -7,6 +7,7 @@
|
||||||
package leveldb
|
package leveldb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
@ -158,6 +159,22 @@ func (tf tFiles) searchNumLess(num int64) int {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Searches smallest index of tables whose its smallest
|
||||||
|
// key is after the given key.
|
||||||
|
func (tf tFiles) searchMinUkey(icmp *iComparer, umin []byte) int {
|
||||||
|
return sort.Search(len(tf), func(i int) bool {
|
||||||
|
return icmp.ucmp.Compare(tf[i].imin.ukey(), umin) > 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searches smallest index of tables whose its largest
|
||||||
|
// key is after the given key.
|
||||||
|
func (tf tFiles) searchMaxUkey(icmp *iComparer, umax []byte) int {
|
||||||
|
return sort.Search(len(tf), func(i int) bool {
|
||||||
|
return icmp.ucmp.Compare(tf[i].imax.ukey(), umax) > 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if given key range overlaps with one or more
|
// Returns true if given key range overlaps with one or more
|
||||||
// tables key range. If unsorted is true then binary search will not be used.
|
// tables key range. If unsorted is true then binary search will not be used.
|
||||||
func (tf tFiles) overlaps(icmp *iComparer, umin, umax []byte, unsorted bool) bool {
|
func (tf tFiles) overlaps(icmp *iComparer, umin, umax []byte, unsorted bool) bool {
|
||||||
|
|
@ -189,6 +206,50 @@ func (tf tFiles) overlaps(icmp *iComparer, umin, umax []byte, unsorted bool) boo
|
||||||
// expanded.
|
// expanded.
|
||||||
// The dst content will be overwritten.
|
// The dst content will be overwritten.
|
||||||
func (tf tFiles) getOverlaps(dst tFiles, icmp *iComparer, umin, umax []byte, overlapped bool) tFiles {
|
func (tf tFiles) getOverlaps(dst tFiles, icmp *iComparer, umin, umax []byte, overlapped bool) tFiles {
|
||||||
|
// Short circuit if tf is empty
|
||||||
|
if len(tf) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// For non-zero levels, there is no ukey hop across at all.
|
||||||
|
// And what's more, the files in these levels are strictly sorted,
|
||||||
|
// so use binary search instead of heavy traverse.
|
||||||
|
if !overlapped {
|
||||||
|
var begin, end int
|
||||||
|
// Determine the begin index of the overlapped file
|
||||||
|
if umin != nil {
|
||||||
|
index := tf.searchMinUkey(icmp, umin)
|
||||||
|
if index == 0 {
|
||||||
|
begin = 0
|
||||||
|
} else if bytes.Compare(tf[index-1].imax.ukey(), umin) >= 0 {
|
||||||
|
// The min ukey overlaps with the index-1 file, expand it.
|
||||||
|
begin = index - 1
|
||||||
|
} else {
|
||||||
|
begin = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Determine the end index of the overlapped file
|
||||||
|
if umax != nil {
|
||||||
|
index := tf.searchMaxUkey(icmp, umax)
|
||||||
|
if index == len(tf) {
|
||||||
|
end = len(tf)
|
||||||
|
} else if bytes.Compare(tf[index].imin.ukey(), umax) <= 0 {
|
||||||
|
// The max ukey overlaps with the index file, expand it.
|
||||||
|
end = index + 1
|
||||||
|
} else {
|
||||||
|
end = index
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
end = len(tf)
|
||||||
|
}
|
||||||
|
// Ensure the overlapped file indexes are valid.
|
||||||
|
if begin >= end {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
dst = make([]*tFile, end-begin)
|
||||||
|
copy(dst, tf[begin:end])
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
dst = dst[:0]
|
dst = dst[:0]
|
||||||
for i := 0; i < len(tf); {
|
for i := 0; i < len(tf); {
|
||||||
t := tf[i]
|
t := tf[i]
|
||||||
|
|
@ -201,12 +262,10 @@ func (tf tFiles) getOverlaps(dst tFiles, icmp *iComparer, umin, umax []byte, ove
|
||||||
} else if umax != nil && icmp.uCompare(t.imax.ukey(), umax) > 0 {
|
} else if umax != nil && icmp.uCompare(t.imax.ukey(), umax) > 0 {
|
||||||
umax = t.imax.ukey()
|
umax = t.imax.ukey()
|
||||||
// Restart search if it is overlapped.
|
// Restart search if it is overlapped.
|
||||||
if overlapped {
|
|
||||||
dst = dst[:0]
|
dst = dst[:0]
|
||||||
i = 0
|
i = 0
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dst = append(dst, t)
|
dst = append(dst, t)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue