mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-03-21 15:45:01 +00:00
lib/mergeset: skip common prefix in binarySearchKey() function
This should improve performance a bit when the search if performed among items with long common prefix
This commit is contained in:
parent
3dacdcb707
commit
0c49552849
1 changed files with 26 additions and 18 deletions
|
@ -138,16 +138,7 @@ func (ps *partSearch) Seek(k []byte) {
|
||||||
items := ps.ib.items
|
items := ps.ib.items
|
||||||
data := ps.ib.data
|
data := ps.ib.data
|
||||||
cpLen := commonPrefixLen(ps.ib.commonPrefix, k)
|
cpLen := commonPrefixLen(ps.ib.commonPrefix, k)
|
||||||
if cpLen > 0 {
|
ps.ibItemIdx = binarySearchKey(data, items, k, cpLen)
|
||||||
keySuffix := k[cpLen:]
|
|
||||||
ps.ibItemIdx = sort.Search(len(items), func(i int) bool {
|
|
||||||
it := items[i]
|
|
||||||
it.Start += uint32(cpLen)
|
|
||||||
return string(keySuffix) <= it.String(data)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
ps.ibItemIdx = binarySearchKey(data, items, k)
|
|
||||||
}
|
|
||||||
if ps.ibItemIdx < len(items) {
|
if ps.ibItemIdx < len(items) {
|
||||||
// The item has been found.
|
// The item has been found.
|
||||||
return
|
return
|
||||||
|
@ -165,14 +156,18 @@ func (ps *partSearch) tryFastSeek(k []byte) bool {
|
||||||
if ps.ib == nil {
|
if ps.ib == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
data := ps.ib.data
|
|
||||||
items := ps.ib.items
|
items := ps.ib.items
|
||||||
idx := ps.ibItemIdx
|
idx := ps.ibItemIdx
|
||||||
if idx >= len(items) {
|
if idx >= len(items) {
|
||||||
// The ib is exhausted.
|
// The ib is exhausted.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if string(k) > items[len(items)-1].String(data) {
|
cpLen := commonPrefixLen(ps.ib.commonPrefix, k)
|
||||||
|
suffix := k[cpLen:]
|
||||||
|
it := items[len(items)-1]
|
||||||
|
it.Start += uint32(cpLen)
|
||||||
|
data := ps.ib.data
|
||||||
|
if string(suffix) > it.String(data) {
|
||||||
// The item is located in next blocks.
|
// The item is located in next blocks.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -181,8 +176,16 @@ func (ps *partSearch) tryFastSeek(k []byte) bool {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
idx--
|
idx--
|
||||||
}
|
}
|
||||||
if string(k) < items[idx].String(data) {
|
it = items[idx]
|
||||||
if string(k) < items[0].String(data) {
|
it.Start += uint32(cpLen)
|
||||||
|
if string(suffix) < it.String(data) {
|
||||||
|
items = items[:idx]
|
||||||
|
if len(items) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
it = items[0]
|
||||||
|
it.Start += uint32(cpLen)
|
||||||
|
if string(suffix) < it.String(data) {
|
||||||
// The item is located in previous blocks.
|
// The item is located in previous blocks.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -190,7 +193,7 @@ func (ps *partSearch) tryFastSeek(k []byte) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The item is located in the current block
|
// The item is located in the current block
|
||||||
ps.ibItemIdx = idx + binarySearchKey(data, items[idx:], k)
|
ps.ibItemIdx = idx + binarySearchKey(data, items[idx:], k, cpLen)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,11 +333,14 @@ func (ps *partSearch) readInmemoryBlock(bh *blockHeader) (*inmemoryBlock, error)
|
||||||
return ib, nil
|
return ib, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func binarySearchKey(data []byte, items []Item, key []byte) int {
|
func binarySearchKey(data []byte, items []Item, k []byte, cpLen int) int {
|
||||||
if len(items) == 0 {
|
if len(items) == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if string(key) <= items[0].String(data) {
|
suffix := k[cpLen:]
|
||||||
|
it := items[0]
|
||||||
|
it.Start += uint32(cpLen)
|
||||||
|
if string(suffix) <= it.String(data) {
|
||||||
// Fast path - the item is the first.
|
// Fast path - the item is the first.
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -346,7 +352,9 @@ func binarySearchKey(data []byte, items []Item, key []byte) int {
|
||||||
i, j := uint(0), n
|
i, j := uint(0), n
|
||||||
for i < j {
|
for i < j {
|
||||||
h := uint(i+j) >> 1
|
h := uint(i+j) >> 1
|
||||||
if h >= 0 && h < uint(len(items)) && string(key) > items[h].String(data) {
|
it := items[h]
|
||||||
|
it.Start += uint32(cpLen)
|
||||||
|
if h >= 0 && h < uint(len(items)) && string(suffix) > it.String(data) {
|
||||||
i = h + 1
|
i = h + 1
|
||||||
} else {
|
} else {
|
||||||
j = h
|
j = h
|
||||||
|
|
Loading…
Reference in a new issue