mirror of
https://github.com/talent-plan/tinykv.git
synced 2025-01-13 13:50:43 +08:00
5e089a2cd1
Signed-off-by: Connor <zbk602423539@gmail.com> Co-authored-by: Nick Cameron <nrc@ncameron.org> Co-authored-by: linning <linningde25@gmail.com> Co-authored-by: YangKeao <keao.yang@yahoo.com> Co-authored-by: andylokandy <andylokandy@hotmail.com> Co-authored-by: Iosmanthus Teng <myosmanthustree@gmail.com>
193 lines
4.6 KiB
Go
193 lines
4.6 KiB
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,
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/pingcap-incubator/tinykv/proto/pkg/metapb"
|
|
"github.com/pingcap-incubator/tinykv/scheduler/pkg/mock/mockid"
|
|
"github.com/pingcap-incubator/tinykv/scheduler/server/id"
|
|
. "github.com/pingcap/check"
|
|
)
|
|
|
|
func TestCore(t *testing.T) {
|
|
TestingT(t)
|
|
}
|
|
|
|
var _ = Suite(&testRegionMapSuite{})
|
|
|
|
type testRegionMapSuite struct{}
|
|
|
|
func (s *testRegionMapSuite) TestRegionMap(c *C) {
|
|
var empty *regionMap
|
|
c.Assert(empty.Len(), Equals, 0)
|
|
c.Assert(empty.Get(1), IsNil)
|
|
|
|
rm := newRegionMap()
|
|
s.check(c, rm)
|
|
rm.Put(s.regionInfo(1))
|
|
s.check(c, rm, 1)
|
|
|
|
rm.Put(s.regionInfo(2))
|
|
rm.Put(s.regionInfo(3))
|
|
s.check(c, rm, 1, 2, 3)
|
|
|
|
rm.Put(s.regionInfo(3))
|
|
rm.Delete(4)
|
|
s.check(c, rm, 1, 2, 3)
|
|
|
|
rm.Delete(3)
|
|
rm.Delete(1)
|
|
s.check(c, rm, 2)
|
|
|
|
rm.Put(s.regionInfo(3))
|
|
s.check(c, rm, 2, 3)
|
|
}
|
|
|
|
func (s *testRegionMapSuite) regionInfo(id uint64) *RegionInfo {
|
|
return &RegionInfo{
|
|
meta: &metapb.Region{
|
|
Id: id,
|
|
},
|
|
approximateSize: int64(id),
|
|
}
|
|
}
|
|
|
|
func (s *testRegionMapSuite) check(c *C, rm *regionMap, ids ...uint64) {
|
|
// Check Get.
|
|
for _, id := range ids {
|
|
c.Assert(rm.Get(id).GetID(), Equals, id)
|
|
}
|
|
// Check Len.
|
|
c.Assert(rm.Len(), Equals, len(ids))
|
|
// Check id set.
|
|
expect := make(map[uint64]struct{})
|
|
for _, id := range ids {
|
|
expect[id] = struct{}{}
|
|
}
|
|
set1 := make(map[uint64]struct{})
|
|
for _, r := range rm.m {
|
|
set1[r.GetID()] = struct{}{}
|
|
}
|
|
c.Assert(set1, DeepEquals, expect)
|
|
// Check region size.
|
|
var total int64
|
|
for _, id := range ids {
|
|
total += int64(id)
|
|
}
|
|
c.Assert(rm.TotalSize(), Equals, total)
|
|
}
|
|
|
|
var _ = Suite(&testRegionKey{})
|
|
|
|
type testRegionKey struct{}
|
|
|
|
func (*testRegionKey) TestRegionKey(c *C) {
|
|
testCase := []struct {
|
|
key string
|
|
expect string
|
|
}{
|
|
{`"t\x80\x00\x00\x00\x00\x00\x00\xff!_r\x80\x00\x00\x00\x00\xff\x02\u007fY\x00\x00\x00\x00\x00\xfa"`,
|
|
`7480000000000000FF215F728000000000FF027F590000000000FA`},
|
|
{"\"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xf8\"",
|
|
`80000000000000FF0500000000000000F8`},
|
|
}
|
|
for _, t := range testCase {
|
|
got, err := strconv.Unquote(t.key)
|
|
c.Assert(err, IsNil)
|
|
s := fmt.Sprintln(RegionToHexMeta(&metapb.Region{StartKey: []byte(got)}))
|
|
c.Assert(strings.Contains(s, t.expect), IsTrue)
|
|
|
|
// start key changed
|
|
orgion := NewRegionInfo(&metapb.Region{EndKey: []byte(got)}, nil)
|
|
region := NewRegionInfo(&metapb.Region{StartKey: []byte(got), EndKey: []byte(got)}, nil)
|
|
s = DiffRegionKeyInfo(orgion, region)
|
|
c.Assert(s, Matches, ".*StartKey Changed.*")
|
|
c.Assert(strings.Contains(s, t.expect), IsTrue)
|
|
|
|
// end key changed
|
|
orgion = NewRegionInfo(&metapb.Region{StartKey: []byte(got)}, nil)
|
|
region = NewRegionInfo(&metapb.Region{StartKey: []byte(got), EndKey: []byte(got)}, nil)
|
|
s = DiffRegionKeyInfo(orgion, region)
|
|
c.Assert(s, Matches, ".*EndKey Changed.*")
|
|
c.Assert(strings.Contains(s, t.expect), IsTrue)
|
|
}
|
|
}
|
|
|
|
func BenchmarkRandomRegion(b *testing.B) {
|
|
regions := NewRegionsInfo()
|
|
for i := 0; i < 5000000; i++ {
|
|
item := &RegionInfo{meta: &metapb.Region{StartKey: []byte(fmt.Sprintf("%20d", i)), EndKey: []byte(fmt.Sprintf("%20d", i+1))}}
|
|
regions.AddRegion(item)
|
|
}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
regions.RandRegion()
|
|
}
|
|
}
|
|
|
|
const keyLength = 100
|
|
|
|
func randomBytes(n int) []byte {
|
|
bytes := make([]byte, n)
|
|
_, err := rand.Read(bytes)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return bytes
|
|
}
|
|
|
|
func newRegionInfoID(idAllocator id.Allocator) *RegionInfo {
|
|
var (
|
|
peers []*metapb.Peer
|
|
leader *metapb.Peer
|
|
)
|
|
for i := 0; i < 3; i++ {
|
|
id, _ := idAllocator.Alloc()
|
|
p := &metapb.Peer{Id: id, StoreId: id}
|
|
if i == 0 {
|
|
leader = p
|
|
}
|
|
peers = append(peers, p)
|
|
}
|
|
regionID, _ := idAllocator.Alloc()
|
|
return NewRegionInfo(
|
|
&metapb.Region{
|
|
Id: regionID,
|
|
StartKey: randomBytes(keyLength),
|
|
EndKey: randomBytes(keyLength),
|
|
Peers: peers,
|
|
},
|
|
leader,
|
|
)
|
|
}
|
|
|
|
func BenchmarkAddRegion(b *testing.B) {
|
|
regions := NewRegionsInfo()
|
|
idAllocator := mockid.NewIDAllocator()
|
|
var items []*RegionInfo
|
|
for i := 0; i < 10000000; i++ {
|
|
items = append(items, newRegionInfoID(idAllocator))
|
|
}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
regions.AddRegion(items[i])
|
|
}
|
|
}
|