mirror of https://github.com/tikv/client-go.git
*: update google/btree to improve performance (#547)
* *: update google/btree to improve performance Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com> * update ci Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
This commit is contained in:
parent
57c12f7c64
commit
86d51ba7eb
|
|
@ -1,6 +1,6 @@
|
|||
module gcworker
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/tikv/client-go/v2 v2.0.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module rawkv
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/tikv/client-go/v2 v2.0.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module 1pc_txn
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/tikv/client-go/v2 v2.0.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module async_commit
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/tikv/client-go/v2 v2.0.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module delete_range
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/tikv/client-go/v2 v2.0.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module txnkv
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/tikv/client-go/v2 v2.0.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module pessimistic_txn
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/tikv/client-go/v2 v2.0.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module unsafedestoryrange
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/tikv/client-go/v2 v2.0.0
|
||||
|
||||
|
|
|
|||
35
go.mod
35
go.mod
|
|
@ -1,18 +1,15 @@
|
|||
module github.com/tikv/client-go/v2
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf // indirect
|
||||
github.com/google/btree v1.0.0
|
||||
github.com/google/btree v1.1.2
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/gomega v1.18.1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00
|
||||
github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989
|
||||
|
|
@ -21,7 +18,6 @@ require (
|
|||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/stathat/consistent v1.0.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/tikv/pd/client v0.0.0-20220307081149-841fa61e9710
|
||||
|
|
@ -33,5 +29,32 @@ require (
|
|||
go.uber.org/zap v1.20.0
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
google.golang.org/grpc v1.43.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/benbjohnson/clock v1.1.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/gomega v1.18.1 // indirect
|
||||
github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/common v0.26.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
|
||||
google.golang.org/protobuf v1.26.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
stathat.com/c/consistent v1.0.0 // indirect
|
||||
)
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -84,8 +84,8 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw
|
|||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf h1:gFVkHXmVAhEbxZVDln5V9GKrLaluNoFHDbrZwAWZgws=
|
||||
github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
module integration_tests
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/klauspost/compress v1.15.4 // indirect
|
||||
github.com/ninedraft/israce v0.0.3
|
||||
github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c
|
||||
github.com/pingcap/failpoint v0.0.0-20220423142525-ae43b7f4e5c3
|
||||
github.com/pingcap/kvproto v0.0.0-20220705053936-aa9c2d20cd2a
|
||||
github.com/pingcap/tidb v1.1.0-beta.0.20220706093502-562b03368993
|
||||
github.com/pingcap/tidb/parser v0.0.0-20220706093502-562b03368993 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.7.2-0.20220504104629-106ec21d14df
|
||||
github.com/tidwall/gjson v1.14.1
|
||||
|
|
@ -18,6 +16,75 @@ require (
|
|||
go.uber.org/goleak v1.1.12
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.1.0 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/coocood/bbloom v0.0.0-20190830030839-58deb6228d64 // indirect
|
||||
github.com/coocood/freecache v1.2.1 // indirect
|
||||
github.com/coocood/rtutil v0.0.0-20190304133409-c84515f646f2 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
|
||||
github.com/danjacques/gofslock v0.0.0-20191023191349-0a45f885bc37 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/klauspost/compress v1.15.4 // indirect
|
||||
github.com/klauspost/cpuid v1.3.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/ncw/directio v1.0.5 // indirect
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/opentracing/basictracer-go v1.0.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pingcap/badger v1.5.1-0.20220314162537-ab58fbf40580 // indirect
|
||||
github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 // indirect
|
||||
github.com/pingcap/log v1.1.0 // indirect
|
||||
github.com/pingcap/tidb/parser v0.0.0-20220706093502-562b03368993 // indirect
|
||||
github.com/pingcap/tipb v0.0.0-20220706024432-7be3cc83a7d5 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_golang v1.12.2 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.22.4 // indirect
|
||||
github.com/stathat/consistent v1.0.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/twmb/murmur3 v1.1.3 // indirect
|
||||
github.com/uber/jaeger-client-go v2.22.1+incompatible // indirect
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.2 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.2 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20220428152302-39d4317da171 // indirect
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
|
||||
golang.org/x/tools v0.1.11 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8 // indirect
|
||||
google.golang.org/grpc v1.44.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
||||
replace github.com/tikv/client-go/v2 => ../
|
||||
|
||||
replace github.com/pingcap/tidb => github.com/glorv/tidb v1.1.0-beta.0.20220706085636-88fb3fa642bb
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -371,7 +371,7 @@ type RegionCache struct {
|
|||
sync.RWMutex // mutex protect cached region
|
||||
regions map[RegionVerID]*Region // cached regions are organized as regionVerID to region ref mapping
|
||||
latestVersions map[uint64]RegionVerID // cache the map from regionID to its latest RegionVerID
|
||||
sorted *btree.BTree // cache regions are organized as sorted key to region ref mapping
|
||||
sorted *SortedRegions // cache regions are organized as sorted key to region ref mapping
|
||||
}
|
||||
storeMu struct {
|
||||
sync.RWMutex
|
||||
|
|
@ -410,7 +410,7 @@ func NewRegionCache(pdClient pd.Client) *RegionCache {
|
|||
|
||||
c.mu.regions = make(map[RegionVerID]*Region)
|
||||
c.mu.latestVersions = make(map[uint64]RegionVerID)
|
||||
c.mu.sorted = btree.New(btreeDegree)
|
||||
c.mu.sorted = NewSortedRegions(btreeDegree)
|
||||
c.storeMu.stores = make(map[uint64]*Store)
|
||||
c.tiflashMPPStoreMu.needReload = true
|
||||
c.tiflashMPPStoreMu.stores = make([]*Store, 0)
|
||||
|
|
@ -427,7 +427,7 @@ func (c *RegionCache) clear() {
|
|||
c.mu.Lock()
|
||||
c.mu.regions = make(map[RegionVerID]*Region)
|
||||
c.mu.latestVersions = make(map[uint64]RegionVerID)
|
||||
c.mu.sorted = btree.New(btreeDegree)
|
||||
c.mu.sorted.Clear()
|
||||
c.mu.Unlock()
|
||||
c.storeMu.Lock()
|
||||
c.storeMu.stores = make(map[uint64]*Store)
|
||||
|
|
@ -1284,10 +1284,9 @@ func (c *RegionCache) removeVersionFromCache(oldVer RegionVerID, regionID uint64
|
|||
// insertRegionToCache tries to insert the Region to cache.
|
||||
// It should be protected by c.mu.Lock().
|
||||
func (c *RegionCache) insertRegionToCache(cachedRegion *Region) {
|
||||
old := c.mu.sorted.ReplaceOrInsert(newBtreeItem(cachedRegion))
|
||||
if old != nil {
|
||||
oldRegion := c.mu.sorted.ReplaceOrInsert(cachedRegion)
|
||||
if oldRegion != nil {
|
||||
store := cachedRegion.getStore()
|
||||
oldRegion := old.(*btreeItem).cachedRegion
|
||||
oldRegionStore := oldRegion.getStore()
|
||||
// TODO(youjiali1995): remove this because the new retry logic can handle this issue.
|
||||
//
|
||||
|
|
@ -1328,18 +1327,7 @@ func (c *RegionCache) searchCachedRegion(key []byte, isEndKey bool) *Region {
|
|||
ts := time.Now().Unix()
|
||||
var r *Region
|
||||
c.mu.RLock()
|
||||
c.mu.sorted.DescendLessOrEqual(newBtreeSearchItem(key), func(item btree.Item) bool {
|
||||
r = item.(*btreeItem).cachedRegion
|
||||
if isEndKey && bytes.Equal(r.StartKey(), key) {
|
||||
r = nil // clear result
|
||||
return true // iterate next item
|
||||
}
|
||||
if !r.checkRegionCacheTTL(ts) {
|
||||
r = nil
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
r = c.mu.sorted.DescendLessOrEqual(key, isEndKey, ts)
|
||||
c.mu.RUnlock()
|
||||
if r != nil && (!isEndKey && r.Contains(key) || isEndKey && r.ContainsByEnd(key)) {
|
||||
return r
|
||||
|
|
@ -1532,14 +1520,7 @@ func (c *RegionCache) scanRegionsFromCache(bo *retry.Backoffer, startKey, endKey
|
|||
var regions []*Region
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
c.mu.sorted.AscendGreaterOrEqual(newBtreeSearchItem(startKey), func(item btree.Item) bool {
|
||||
region := item.(*btreeItem).cachedRegion
|
||||
if len(endKey) > 0 && bytes.Compare(region.StartKey(), endKey) >= 0 {
|
||||
return false
|
||||
}
|
||||
regions = append(regions, region)
|
||||
return len(regions) < limit
|
||||
})
|
||||
regions = c.mu.sorted.AscendGreaterOrEqual(startKey, endKey, limit)
|
||||
|
||||
if len(regions) == 0 {
|
||||
return nil, errors.New("no regions in the cache")
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/google/btree"
|
||||
"github.com/pingcap/kvproto/pkg/errorpb"
|
||||
"github.com/pingcap/kvproto/pkg/metapb"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
|
@ -98,7 +97,7 @@ func (s *testRegionCacheSuite) checkCache(len int) {
|
|||
ts := time.Now().Unix()
|
||||
s.Equal(validRegions(s.cache.mu.regions, ts), len)
|
||||
s.Equal(validRegionsSearchedByVersions(s.cache.mu.latestVersions, s.cache.mu.regions, ts), len)
|
||||
s.Equal(validRegionsInBtree(s.cache.mu.sorted, ts), len)
|
||||
s.Equal(s.cache.mu.sorted.ValidRegionsInBtree(ts), len)
|
||||
}
|
||||
|
||||
func validRegionsSearchedByVersions(
|
||||
|
|
@ -126,18 +125,6 @@ func validRegions(regions map[RegionVerID]*Region, ts int64) (len int) {
|
|||
return
|
||||
}
|
||||
|
||||
func validRegionsInBtree(t *btree.BTree, ts int64) (len int) {
|
||||
t.Descend(func(item btree.Item) bool {
|
||||
r := item.(*btreeItem).cachedRegion
|
||||
if !r.checkRegionCacheTTL(ts) {
|
||||
return true
|
||||
}
|
||||
len++
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *testRegionCacheSuite) getRegion(key []byte) *Region {
|
||||
_, err := s.cache.LocateKey(s.bo, key)
|
||||
s.Nil(err)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright 2022 TiKV Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// NOTE: The code in this file is based on code from the
|
||||
// TiDB project, licensed under the Apache License v 2.0
|
||||
//
|
||||
// https://github.com/pingcap/tidb/tree/cc5e161ac06827589c4966674597c137cc9e809c/store/tikv/locate/region_request.go
|
||||
//
|
||||
|
||||
// Copyright 2016 PingCAP, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !go1.18
|
||||
// +build !go1.18
|
||||
|
||||
package locate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/google/btree"
|
||||
)
|
||||
|
||||
// SortedRegionsRegions is a sorted btree.
|
||||
type SortedRegions struct {
|
||||
b *btree.BTree
|
||||
}
|
||||
|
||||
// NewSortedRegions returns a new SortedRegions.
|
||||
func NewSortedRegions(btreeDegree int) *SortedRegions {
|
||||
return &SortedRegions{
|
||||
b: btree.New(btreeDegree),
|
||||
}
|
||||
}
|
||||
|
||||
// ReplaceOrInsert inserts a new item into the btree.
|
||||
func (s *SortedRegions) ReplaceOrInsert(cachedRegion *Region) *Region {
|
||||
old := s.b.ReplaceOrInsert(newBtreeItem(cachedRegion))
|
||||
if old != nil {
|
||||
return old.(*btreeItem).cachedRegion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DescendLessOrEqual returns all items that are less than or equal to the key.
|
||||
func (s *SortedRegions) DescendLessOrEqual(key []byte, isEndKey bool, ts int64) (r *Region) {
|
||||
s.b.DescendLessOrEqual(newBtreeSearchItem(key), func(item btree.Item) bool {
|
||||
r = item.(*btreeItem).cachedRegion
|
||||
if isEndKey && bytes.Equal(r.StartKey(), key) {
|
||||
r = nil // clear result
|
||||
return true // iterate next item
|
||||
}
|
||||
if !r.checkRegionCacheTTL(ts) {
|
||||
r = nil
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
// AscendGreaterOrEqual returns all items that are greater than or equal to the key.
|
||||
func (s *SortedRegions) AscendGreaterOrEqual(startKey, endKey []byte, limit int) (regions []*Region) {
|
||||
s.b.AscendGreaterOrEqual(newBtreeSearchItem(startKey), func(item btree.Item) bool {
|
||||
region := item.(*btreeItem).cachedRegion
|
||||
if len(endKey) > 0 && bytes.Compare(region.StartKey(), endKey) >= 0 {
|
||||
return false
|
||||
}
|
||||
regions = append(regions, region)
|
||||
return len(regions) < limit
|
||||
})
|
||||
return regions
|
||||
}
|
||||
|
||||
// Clear removes all items from the btree.
|
||||
func (s *SortedRegions) Clear() {
|
||||
s.b.Clear(false)
|
||||
}
|
||||
|
||||
// ValidRegionsInBtree returns the number of valid regions in the btree.
|
||||
func (s *SortedRegions) ValidRegionsInBtree(ts int64) (len int) {
|
||||
s.b.Descend(func(item btree.Item) bool {
|
||||
r := item.(*btreeItem).cachedRegion
|
||||
if !r.checkRegionCacheTTL(ts) {
|
||||
return true
|
||||
}
|
||||
len++
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright 2022 TiKV Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// NOTE: The code in this file is based on code from the
|
||||
// TiDB project, licensed under the Apache License v 2.0
|
||||
//
|
||||
// https://github.com/pingcap/tidb/tree/cc5e161ac06827589c4966674597c137cc9e809c/store/tikv/locate/region_request.go
|
||||
//
|
||||
|
||||
// Copyright 2016 PingCAP, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
package locate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/google/btree"
|
||||
)
|
||||
|
||||
// SortedRegions is a sorted btree.
|
||||
type SortedRegions struct {
|
||||
b *btree.BTreeG[*btreeItem]
|
||||
}
|
||||
|
||||
// NewSortedRegions returns a new SortedRegions.
|
||||
func NewSortedRegions(btreeDegree int) *SortedRegions {
|
||||
return &SortedRegions{
|
||||
b: btree.NewG(btreeDegree, func(a, b *btreeItem) bool { return a.Less(b) }),
|
||||
}
|
||||
}
|
||||
|
||||
// ReplaceOrInsert inserts a new item into the btree.
|
||||
func (s *SortedRegions) ReplaceOrInsert(cachedRegion *Region) *Region {
|
||||
old, _ := s.b.ReplaceOrInsert(newBtreeItem(cachedRegion))
|
||||
if old != nil {
|
||||
return old.cachedRegion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DescendLessOrEqual returns all items that are less than or equal to the key.
|
||||
func (s *SortedRegions) DescendLessOrEqual(key []byte, isEndKey bool, ts int64) (r *Region) {
|
||||
s.b.DescendLessOrEqual(newBtreeSearchItem(key), func(item *btreeItem) bool {
|
||||
r = item.cachedRegion
|
||||
if isEndKey && bytes.Equal(r.StartKey(), key) {
|
||||
r = nil // clear result
|
||||
return true // iterate next item
|
||||
}
|
||||
if !r.checkRegionCacheTTL(ts) {
|
||||
r = nil
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
// AscendGreaterOrEqual returns all items that are greater than or equal to the key.
|
||||
func (s *SortedRegions) AscendGreaterOrEqual(startKey, endKey []byte, limit int) (regions []*Region) {
|
||||
s.b.AscendGreaterOrEqual(newBtreeSearchItem(startKey), func(item *btreeItem) bool {
|
||||
region := item.cachedRegion
|
||||
if len(endKey) > 0 && bytes.Compare(region.StartKey(), endKey) >= 0 {
|
||||
return false
|
||||
}
|
||||
regions = append(regions, region)
|
||||
return len(regions) < limit
|
||||
})
|
||||
return regions
|
||||
}
|
||||
|
||||
// Clear removes all items from the btree.
|
||||
func (s *SortedRegions) Clear() {
|
||||
s.b.Clear(false)
|
||||
}
|
||||
|
||||
// ValidRegionsInBtree returns the number of valid regions in the btree.
|
||||
func (s *SortedRegions) ValidRegionsInBtree(ts int64) (len int) {
|
||||
s.b.Descend(func(item *btreeItem) bool {
|
||||
r := item.cachedRegion
|
||||
if !r.checkRegionCacheTTL(ts) {
|
||||
return true
|
||||
}
|
||||
len++
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
Loading…
Reference in New Issue