本文整理匯總了Golang中github.com/cockroachdb/cockroach/pkg/keys.MakeRowSentinelKey函數的典型用法代碼示例。如果您正苦於以下問題:Golang MakeRowSentinelKey函數的具體用法?Golang MakeRowSentinelKey怎麽用?Golang MakeRowSentinelKey使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了MakeRowSentinelKey函數的12個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: monkey
func (z *zeroSum) monkey(tableID uint32, d time.Duration) {
r := newRand()
zipf := z.accountDistribution(r)
for {
time.Sleep(time.Duration(rand.Float64() * float64(d)))
key := keys.MakeTablePrefix(tableID)
key = encoding.EncodeVarintAscending(key, int64(zipf.Uint64()))
key = keys.MakeRowSentinelKey(key)
switch r.Intn(2) {
case 0:
if err := z.Split(z.RandNode(r.Intn), key); err != nil {
if strings.Contains(err.Error(), "range is already split at key") ||
strings.Contains(err.Error(), storage.ErrMsgConflictUpdatingRangeDesc) {
continue
}
z.maybeLogError(err)
} else {
atomic.AddUint64(&z.stats.splits, 1)
}
case 1:
if transferred, err := z.TransferLease(z.RandNode(r.Intn), r, key); err != nil {
z.maybeLogError(err)
} else if transferred {
atomic.AddUint64(&z.stats.transfers, 1)
}
}
}
}
示例2: TestSplitAtTableBoundary
func TestSplitAtTableBoundary(t *testing.T) {
defer leaktest.AfterTest(t)()
testClusterArgs := base.TestClusterArgs{
ReplicationMode: base.ReplicationAuto,
}
tc := testcluster.StartTestCluster(t, 3, testClusterArgs)
defer tc.Stopper().Stop()
runner := sqlutils.MakeSQLRunner(t, tc.Conns[0])
runner.Exec(`CREATE DATABASE test`)
runner.Exec(`CREATE TABLE test.t (k SERIAL PRIMARY KEY, v INT)`)
const tableIDQuery = `
SELECT tables.id FROM system.namespace tables
JOIN system.namespace dbs ON dbs.id = tables.parentid
WHERE dbs.name = $1 AND tables.name = $2
`
var tableID uint32
runner.QueryRow(tableIDQuery, "test", "t").Scan(&tableID)
tableStartKey := keys.MakeTablePrefix(tableID)
// Wait for new table to split.
testutils.SucceedsSoon(t, func() error {
desc, err := tc.LookupRange(keys.MakeRowSentinelKey(tableStartKey))
if err != nil {
t.Fatal(err)
}
if !desc.StartKey.Equal(tableStartKey) {
log.Infof(context.TODO(), "waiting on split results")
return errors.Errorf("expected range start key %s; got %s", tableStartKey, desc.StartKey)
}
return nil
})
}
示例3: EncodeSecondaryIndex
// EncodeSecondaryIndex encodes key/values for a secondary index. colMap maps
// ColumnIDs to indices in `values`.
func EncodeSecondaryIndex(
tableDesc *TableDescriptor,
secondaryIndex *IndexDescriptor,
colMap map[ColumnID]int,
values []parser.Datum,
) (IndexEntry, error) {
secondaryIndexKeyPrefix := MakeIndexKeyPrefix(tableDesc, secondaryIndex.ID)
secondaryIndexKey, containsNull, err := EncodeIndexKey(
tableDesc, secondaryIndex, colMap, values, secondaryIndexKeyPrefix)
if err != nil {
return IndexEntry{}, err
}
// Add the implicit columns - they are encoded ascendingly which is done by
// passing nil for the encoding directions.
extraKey, _, err := EncodeColumns(secondaryIndex.ImplicitColumnIDs, nil,
colMap, values, nil)
if err != nil {
return IndexEntry{}, err
}
entry := IndexEntry{Key: secondaryIndexKey}
if !secondaryIndex.Unique || containsNull {
// If the index is not unique or it contains a NULL value, append
// extraKey to the key in order to make it unique.
entry.Key = append(entry.Key, extraKey...)
}
// Index keys are considered "sentinel" keys in that they do not have a
// column ID suffix.
entry.Key = keys.MakeRowSentinelKey(entry.Key)
if secondaryIndex.Unique {
// Note that a unique secondary index that contains a NULL column value
// will have extraKey appended to the key and stored in the value. We
// require extraKey to be appended to the key in order to make the key
// unique. We could potentially get rid of the duplication here but at
// the expense of complicating scanNode when dealing with unique
// secondary indexes.
entry.Value.SetBytes(extraKey)
} else {
// The zero value for an index-key is a 0-length bytes value.
entry.Value.SetBytes([]byte{})
}
return entry, nil
}
示例4: fillTestRange
func fillTestRange(t testing.TB, rep *Replica, size int64) {
src := rand.New(rand.NewSource(0))
for i := int64(0); i < size/int64(keySize+valSize); i++ {
key := keys.MakeRowSentinelKey(randutil.RandBytes(src, keySize))
val := randutil.RandBytes(src, valSize)
pArgs := putArgs(key, val)
if _, pErr := client.SendWrappedWith(context.Background(), rep, roachpb.Header{
RangeID: rangeID,
}, &pArgs); pErr != nil {
t.Fatal(pErr)
}
}
rep.mu.Lock()
after := rep.mu.state.Stats.Total()
rep.mu.Unlock()
if after < size {
t.Fatalf("range not full after filling: wrote %d, but range at %d", size, after)
}
}
示例5: splitRangeAtVal
// splitRangeAtVal splits the range for a table with schema
// `CREATE TABLE test (k INT PRIMARY KEY)` at row with value pk (the row will be
// the first on the right of the split).
func splitRangeAtVal(
ts *server.TestServer, tableDesc *sqlbase.TableDescriptor, pk int,
) (roachpb.RangeDescriptor, roachpb.RangeDescriptor, error) {
if len(tableDesc.Indexes) != 0 {
return roachpb.RangeDescriptor{}, roachpb.RangeDescriptor{},
errors.Errorf("expected table with just a PK, got: %+v", tableDesc)
}
pik, err := sqlbase.MakePrimaryIndexKey(tableDesc, pk)
if err != nil {
return roachpb.RangeDescriptor{}, roachpb.RangeDescriptor{}, err
}
startKey := keys.MakeRowSentinelKey(pik)
leftRange, rightRange, err := ts.SplitRange(startKey)
if err != nil {
return roachpb.RangeDescriptor{}, roachpb.RangeDescriptor{},
errors.Wrapf(err, "failed to split at row: %d", pk)
}
return leftRange, rightRange, nil
}
示例6: TestReplicateQueueRebalance
func TestReplicateQueueRebalance(t *testing.T) {
defer leaktest.AfterTest(t)()
// Set the gossip stores interval lower to speed up rebalancing. With the
// default of 5s we have to wait ~5s for the rebalancing to start.
defer func(v time.Duration) {
gossip.GossipStoresInterval = v
}(gossip.GossipStoresInterval)
gossip.GossipStoresInterval = 100 * time.Millisecond
// TODO(peter): Remove when lease rebalancing is the default.
defer func(v bool) {
storage.EnableLeaseRebalancing = v
}(storage.EnableLeaseRebalancing)
storage.EnableLeaseRebalancing = true
const numNodes = 5
tc := testcluster.StartTestCluster(t, numNodes,
base.TestClusterArgs{ReplicationMode: base.ReplicationAuto},
)
defer tc.Stopper().Stop()
const newRanges = 5
for i := 0; i < newRanges; i++ {
tableID := keys.MaxReservedDescID + i + 1
splitKey := keys.MakeRowSentinelKey(keys.MakeTablePrefix(uint32(tableID)))
for {
if _, _, err := tc.SplitRange(splitKey); err != nil {
if testutils.IsError(err, "split at key .* failed: conflict updating range descriptors") ||
testutils.IsError(err, "range is already split at key") {
continue
}
t.Fatal(err)
}
break
}
}
countReplicas := func() []int {
counts := make([]int, len(tc.Servers))
for _, s := range tc.Servers {
err := s.Stores().VisitStores(func(s *storage.Store) error {
counts[s.StoreID()-1] += s.ReplicaCount()
return nil
})
if err != nil {
t.Fatal(err)
}
}
return counts
}
numRanges := newRanges + server.ExpectedInitialRangeCount()
numReplicas := numRanges * 3
const minThreshold = 0.9
minReplicas := int(math.Floor(minThreshold * (float64(numReplicas) / numNodes)))
util.SucceedsSoon(t, func() error {
counts := countReplicas()
for _, c := range counts {
if c < minReplicas {
err := errors.Errorf("not balanced: %d", counts)
log.Info(context.Background(), err)
return err
}
}
return nil
})
}
示例7: TestSplitAt
//.........這裏部分代碼省略.........
s STRING,
PRIMARY KEY (i, s),
INDEX s_idx (s)
)`)
r.Exec(`CREATE TABLE d.i (k INT PRIMARY KEY)`)
tests := []struct {
in string
error string
args []interface{}
}{
{
in: "ALTER TABLE d.t SPLIT AT (2, 'b')",
},
{
in: "ALTER TABLE d.t SPLIT AT (2, 'b')",
error: "range is already split",
},
{
in: "ALTER TABLE d.t SPLIT AT ('c', 3)",
error: "argument of SPLIT AT must be type int, not type string",
},
{
in: "ALTER TABLE d.t SPLIT AT (4)",
error: "expected 2 expressions, got 1",
},
{
in: "ALTER TABLE d.t SPLIT AT (5, 'e')",
},
{
in: "ALTER TABLE d.t SPLIT AT (i, s)",
error: `name "i" is not defined`,
},
{
in: "ALTER INDEX [email protected]_idx SPLIT AT ('f')",
},
{
in: "ALTER INDEX [email protected]_present SPLIT AT ('g')",
error: `index "not_present" does not exist`,
},
{
in: "ALTER TABLE d.i SPLIT AT (avg(1))",
error: "unknown signature: avg(int) (desired <int>)",
},
{
in: "ALTER TABLE d.i SPLIT AT (avg(k))",
error: `avg(): name "k" is not defined`,
},
{
in: "ALTER TABLE d.i SPLIT AT ($1)",
args: []interface{}{8},
},
{
in: "ALTER TABLE d.i SPLIT AT ($1)",
error: "no value provided for placeholder: $1",
},
{
in: "ALTER TABLE d.i SPLIT AT ($1)",
args: []interface{}{"blah"},
error: "error in argument for $1: strconv.ParseInt",
},
{
in: "ALTER TABLE d.i SPLIT AT ($1::string)",
args: []interface{}{"1"},
error: "argument of SPLIT AT must be type int, not type string",
},
{
in: "ALTER TABLE d.i SPLIT AT ((SELECT 1))",
},
{
in: "ALTER TABLE d.i SPLIT AT ((SELECT 1, 2))",
error: "subquery must return only one column, found 2",
},
}
for _, tt := range tests {
var key roachpb.Key
var pretty string
err := db.QueryRow(tt.in, tt.args...).Scan(&key, &pretty)
if err != nil && tt.error == "" {
t.Fatalf("%s: unexpected error: %s", tt.in, err)
} else if tt.error != "" && err == nil {
t.Fatalf("%s: expected error: %s", tt.in, tt.error)
} else if err != nil && tt.error != "" {
if !strings.Contains(err.Error(), tt.error) {
t.Fatalf("%s: unexpected error: %s", tt.in, err)
}
} else {
// Successful split, verify it happened.
rng, err := s.(*server.TestServer).LookupRange(key)
if err != nil {
t.Fatal(err)
}
expect := roachpb.Key(keys.MakeRowSentinelKey(rng.StartKey))
if !expect.Equal(key) {
t.Fatalf("%s: expected range start %s, got %s", tt.in, pretty, expect)
}
}
}
}
示例8: TestAmbiguousCommitDueToLeadershipChange
// TestAmbiguousCommitDueToLeadershipChange verifies that an ambiguous
// commit error is returned from sql.Exec in situations where an
// EndTransaction is part of a batch and the disposition of the batch
// request is unknown after a network failure or timeout. The goal
// here is to prevent spurious transaction retries after the initial
// transaction actually succeeded. In cases where there's an
// auto-generated primary key, this can result in silent
// duplications. In cases where the primary key is specified in
// advance, it can result in violated uniqueness constraints, or
// duplicate key violations. See #6053, #7604, and #10023.
func TestAmbiguousCommitDueToLeadershipChange(t *testing.T) {
defer leaktest.AfterTest(t)()
t.Skip("#10341")
// Create a command filter which prevents EndTransaction from
// returning a response.
params := base.TestServerArgs{}
committed := make(chan struct{})
wait := make(chan struct{})
var tableStartKey atomic.Value
var responseCount int32
// Prevent the first conditional put on table 51 from returning to
// waiting client in order to simulate a lost update or slow network
// link.
params.Knobs.Store = &storage.StoreTestingKnobs{
TestingResponseFilter: func(ba roachpb.BatchRequest, br *roachpb.BatchResponse) *roachpb.Error {
req, ok := ba.GetArg(roachpb.ConditionalPut)
tsk := tableStartKey.Load()
if tsk == nil {
return nil
}
if !ok || !bytes.HasPrefix(req.Header().Key, tsk.([]byte)) {
return nil
}
// If this is the first write to the table, wait to respond to the
// client in order to simulate a retry.
if atomic.AddInt32(&responseCount, 1) == 1 {
close(committed)
<-wait
}
return nil
},
}
testClusterArgs := base.TestClusterArgs{
ReplicationMode: base.ReplicationAuto,
ServerArgs: params,
}
const numReplicas = 3
tc := testcluster.StartTestCluster(t, numReplicas, testClusterArgs)
defer tc.Stopper().Stop()
sqlDB := sqlutils.MakeSQLRunner(t, tc.Conns[0])
sqlDB.Exec(`CREATE DATABASE test`)
sqlDB.Exec(`CREATE TABLE test.t (k SERIAL PRIMARY KEY, v INT)`)
tableID := sqlutils.QueryTableID(t, tc.Conns[0], "test", "t")
tableStartKey.Store(keys.MakeTablePrefix(tableID))
// Wait for new table to split.
util.SucceedsSoon(t, func() error {
startKey := tableStartKey.Load().([]byte)
desc, err := tc.LookupRange(keys.MakeRowSentinelKey(startKey))
if err != nil {
t.Fatal(err)
}
if !desc.StartKey.Equal(startKey) {
return errors.Errorf("expected range start key %s; got %s",
startKey, desc.StartKey)
}
return nil
})
// Lookup the lease.
tableRangeDesc, err := tc.LookupRange(keys.MakeRowSentinelKey(tableStartKey.Load().([]byte)))
if err != nil {
t.Fatal(err)
}
leaseHolder, err := tc.FindRangeLeaseHolder(
&tableRangeDesc,
&testcluster.ReplicationTarget{
NodeID: tc.Servers[0].GetNode().Descriptor.NodeID,
StoreID: tc.Servers[0].GetFirstStoreID(),
})
if err != nil {
t.Fatal(err)
}
// In a goroutine, send an insert which will commit but not return
// from the leader (due to the command filter we installed on node 0).
sqlErrCh := make(chan error, 1)
go func() {
// Use a connection other than through the node which is the current
// leaseholder to ensure that we use GRPC instead of the local server.
// If we use a local server, the hanging response we simulate takes
// up the dist sender thread of execution because local requests are
// executed synchronously.
sqlConn := tc.Conns[leaseHolder.NodeID%numReplicas]
//.........這裏部分代碼省略.........
示例9: TestManualReplication
func TestManualReplication(t *testing.T) {
defer leaktest.AfterTest(t)()
tc := StartTestCluster(t, 3,
base.TestClusterArgs{
ReplicationMode: base.ReplicationManual,
ServerArgs: base.TestServerArgs{
UseDatabase: "t",
},
})
defer tc.Stopper().Stop()
s0 := sqlutils.MakeSQLRunner(t, tc.Conns[0])
s1 := sqlutils.MakeSQLRunner(t, tc.Conns[1])
s2 := sqlutils.MakeSQLRunner(t, tc.Conns[2])
s0.Exec(`CREATE DATABASE t`)
s0.Exec(`CREATE TABLE test (k INT PRIMARY KEY, v INT)`)
s0.Exec(`INSERT INTO test VALUES (5, 1), (4, 2), (1, 2)`)
if r := s1.Query(`SELECT * FROM test WHERE k = 5`); !r.Next() {
t.Fatal("no rows")
}
s2.ExecRowsAffected(3, `DELETE FROM test`)
// Split the table to a new range.
kvDB := tc.Servers[0].DB()
tableDesc := sqlbase.GetTableDescriptor(kvDB, "t", "test")
tableStartKey := keys.MakeRowSentinelKey(keys.MakeTablePrefix(uint32(tableDesc.ID)))
leftRangeDesc, tableRangeDesc, err := tc.SplitRange(tableStartKey)
if err != nil {
t.Fatal(err)
}
log.Infof(context.Background(), "After split got ranges: %+v and %+v.", leftRangeDesc, tableRangeDesc)
if len(tableRangeDesc.Replicas) == 0 {
t.Fatalf(
"expected replica on node 1, got no replicas: %+v", tableRangeDesc.Replicas)
}
if tableRangeDesc.Replicas[0].NodeID != 1 {
t.Fatalf(
"expected replica on node 1, got replicas: %+v", tableRangeDesc.Replicas)
}
// Replicate the table's range to all the nodes.
tableRangeDesc, err = tc.AddReplicas(
tableRangeDesc.StartKey.AsRawKey(), tc.Target(1), tc.Target(2),
)
if err != nil {
t.Fatal(err)
}
if len(tableRangeDesc.Replicas) != 3 {
t.Fatalf("expected 3 replicas, got %+v", tableRangeDesc.Replicas)
}
for i := 0; i < 3; i++ {
if _, ok := tableRangeDesc.GetReplicaDescriptor(
tc.Servers[i].GetFirstStoreID()); !ok {
t.Fatalf("expected replica on store %d, got %+v",
tc.Servers[i].GetFirstStoreID(), tableRangeDesc.Replicas)
}
}
// Transfer the lease to node 1.
leaseHolder, err := tc.FindRangeLeaseHolder(
tableRangeDesc,
&ReplicationTarget{
NodeID: tc.Servers[0].GetNode().Descriptor.NodeID,
StoreID: tc.Servers[0].GetFirstStoreID(),
})
if err != nil {
t.Fatal(err)
}
if leaseHolder.StoreID != tc.Servers[0].GetFirstStoreID() {
t.Fatalf("expected initial lease on server idx 0, but is on node: %+v",
leaseHolder)
}
err = tc.TransferRangeLease(tableRangeDesc, tc.Target(1))
if err != nil {
t.Fatal(err)
}
// Check that the lease holder has changed. We'll use the old lease holder as
// the hint, since it's guaranteed that the old lease holder has applied the
// new lease.
leaseHolder, err = tc.FindRangeLeaseHolder(
tableRangeDesc,
&ReplicationTarget{
NodeID: tc.Servers[0].GetNode().Descriptor.NodeID,
StoreID: tc.Servers[0].GetFirstStoreID(),
})
if err != nil {
t.Fatal(err)
}
if leaseHolder.StoreID != tc.Servers[1].GetFirstStoreID() {
t.Fatalf("expected lease on server idx 1 (node: %d store: %d), but is on node: %+v",
tc.Servers[1].GetNode().Descriptor.NodeID,
tc.Servers[1].GetFirstStoreID(),
leaseHolder)
//.........這裏部分代碼省略.........
示例10: BenchmarkSstRekey
func BenchmarkSstRekey(b *testing.B) {
// TODO(dan): DRY this with BenchmarkRocksDBSstFileReader.
dir, cleanupFn := testutils.TempDir(b, 1)
defer cleanupFn()
sstPath := filepath.Join(dir, "sst")
{
const maxEntries = 100000
const keyLen = 10
const valLen = 100
b.SetBytes(keyLen + valLen)
ts := hlc.Timestamp{WallTime: timeutil.Now().UnixNano()}
kv := engine.MVCCKeyValue{
Key: engine.MVCCKey{Key: roachpb.Key(make([]byte, keyLen)), Timestamp: ts},
Value: make([]byte, valLen),
}
sst := engine.MakeRocksDBSstFileWriter()
if err := sst.Open(sstPath); err != nil {
b.Fatal(sst)
}
var entries = b.N
if entries > maxEntries {
entries = maxEntries
}
for i := 0; i < entries; i++ {
payload := []byte(fmt.Sprintf("%09d", i))
kv.Key.Key = kv.Key.Key[:0]
kv.Key.Key = encoding.EncodeUvarintAscending(kv.Key.Key, uint64(i)) // tableID
kv.Key.Key = encoding.EncodeUvarintAscending(kv.Key.Key, 0) // indexID
kv.Key.Key = encoding.EncodeBytesAscending(kv.Key.Key, payload)
kv.Key.Key = keys.MakeRowSentinelKey(kv.Key.Key)
copy(kv.Value, payload)
if err := sst.Add(kv); err != nil {
b.Fatal(err)
}
}
if err := sst.Close(); err != nil {
b.Fatal(err)
}
}
const newTableID = 100
b.ResetTimer()
sst, err := engine.MakeRocksDBSstFileReader()
if err != nil {
b.Fatal(err)
}
if err := sst.AddFile(sstPath); err != nil {
b.Fatal(err)
}
defer sst.Close()
count := 0
iterateFn := sql.MakeRekeyMVCCKeyValFunc(newTableID, func(kv engine.MVCCKeyValue) (bool, error) {
count++
if count >= b.N {
return true, nil
}
return false, nil
})
for {
if err := sst.Iterate(engine.MVCCKey{Key: keys.MinKey}, engine.MVCCKey{Key: keys.MaxKey}, iterateFn); err != nil {
b.Fatal(err)
}
if count >= b.N {
break
}
}
}
示例11: ComputeSplitKeys
// ComputeSplitKeys takes a start and end key and returns an array of keys
// at which to split the span [start, end).
// The only required splits are at each user table prefix.
func (s SystemConfig) ComputeSplitKeys(startKey, endKey roachpb.RKey) []roachpb.RKey {
tableStart := roachpb.RKey(keys.SystemConfigTableDataMax)
if !tableStart.Less(endKey) {
// This range is before the user tables span: no required splits.
return nil
}
startID, ok := ObjectIDForKey(startKey)
if !ok || startID <= keys.MaxSystemConfigDescID {
// The start key is either:
// - not part of the structured data span
// - part of the system span
// In either case, start looking for splits at the first ID usable
// by the user data span.
startID = keys.MaxSystemConfigDescID + 1
} else {
// The start key is either already a split key, or after the split
// key for its ID. We can skip straight to the next one.
startID++
}
// Build key prefixes for sequential table IDs until we reach endKey. Note
// that there are two disjoint sets of sequential keys: non-system reserved
// tables have sequential IDs, as do user tables, but the two ranges contain a
// gap.
var splitKeys []roachpb.RKey
var key roachpb.RKey
// appendSplitKeys generates all possible split keys between the given range
// of IDs and adds them to splitKeys.
appendSplitKeys := func(startID, endID uint32) {
// endID could be smaller than startID if we don't have user tables.
for id := startID; id <= endID; id++ {
key = keys.MakeRowSentinelKey(keys.MakeTablePrefix(id))
// Skip if this ID matches the startKey passed to ComputeSplitKeys.
if !startKey.Less(key) {
continue
}
// Handle the case where EndKey is already a table prefix.
if !key.Less(endKey) {
break
}
splitKeys = append(splitKeys, key)
}
}
// If the startKey falls within the non-system reserved range, compute those
// keys first.
if startID <= keys.MaxReservedDescID {
endID, err := s.GetLargestObjectID(keys.MaxReservedDescID)
if err != nil {
log.Errorf(context.TODO(), "unable to determine largest reserved object ID from system config: %s", err)
return nil
}
appendSplitKeys(startID, endID)
startID = keys.MaxReservedDescID + 1
}
// Append keys in the user space.
endID, err := s.GetLargestObjectID(0)
if err != nil {
log.Errorf(context.TODO(), "unable to determine largest object ID from system config: %s", err)
return nil
}
appendSplitKeys(startID, endID)
return splitKeys
}
示例12: TestComputeSplits
func TestComputeSplits(t *testing.T) {
defer leaktest.AfterTest(t)()
const (
start = keys.MaxReservedDescID + 1
reservedStart = keys.MaxSystemConfigDescID + 1
)
schema := sqlbase.MakeMetadataSchema()
// Real system tables only.
baseSql := schema.GetInitialValues()
// Real system tables plus some user stuff.
allSql := append(schema.GetInitialValues(),
descriptor(start), descriptor(start+1), descriptor(start+5))
sort.Sort(roachpb.KeyValueByKey(allSql))
allUserSplits := []uint32{start, start + 1, start + 2, start + 3, start + 4, start + 5}
var allReservedSplits []uint32
for i := 0; i < schema.SystemDescriptorCount()-schema.SystemConfigDescriptorCount(); i++ {
allReservedSplits = append(allReservedSplits, reservedStart+uint32(i))
}
allSplits := append(allReservedSplits, allUserSplits...)
testCases := []struct {
values []roachpb.KeyValue
start, end roachpb.RKey
// Use ints in the testcase definitions, more readable.
splits []uint32
}{
// No data.
{nil, roachpb.RKeyMin, roachpb.RKeyMax, nil},
{nil, keys.MakeTablePrefix(start), roachpb.RKeyMax, nil},
{nil, keys.MakeTablePrefix(start), keys.MakeTablePrefix(start + 10), nil},
{nil, roachpb.RKeyMin, keys.MakeTablePrefix(start + 10), nil},
// Reserved descriptors.
{baseSql, roachpb.RKeyMin, roachpb.RKeyMax, allReservedSplits},
{baseSql, keys.MakeTablePrefix(start), roachpb.RKeyMax, nil},
{baseSql, keys.MakeTablePrefix(start), keys.MakeTablePrefix(start + 10), nil},
{baseSql, roachpb.RKeyMin, keys.MakeTablePrefix(start + 10), allReservedSplits},
{baseSql, keys.MakeTablePrefix(reservedStart), roachpb.RKeyMax, allReservedSplits[1:]},
{baseSql, keys.MakeTablePrefix(reservedStart), keys.MakeTablePrefix(start + 10), allReservedSplits[1:]},
{baseSql, roachpb.RKeyMin, keys.MakeTablePrefix(reservedStart + 2), allReservedSplits[:2]},
{baseSql, roachpb.RKeyMin, keys.MakeTablePrefix(reservedStart + 10), allReservedSplits},
{baseSql, keys.MakeTablePrefix(reservedStart), keys.MakeTablePrefix(reservedStart + 2), allReservedSplits[1:2]},
{baseSql, testutils.MakeKey(keys.MakeTablePrefix(reservedStart), roachpb.RKey("foo")),
testutils.MakeKey(keys.MakeTablePrefix(start+10), roachpb.RKey("foo")), allReservedSplits[1:]},
// Reserved + User descriptors.
{allSql, keys.MakeTablePrefix(start - 1), roachpb.RKeyMax, allUserSplits},
{allSql, keys.MakeTablePrefix(start), roachpb.RKeyMax, allUserSplits[1:]},
{allSql, keys.MakeTablePrefix(start), keys.MakeTablePrefix(start + 10), allUserSplits[1:]},
{allSql, keys.MakeTablePrefix(start - 1), keys.MakeTablePrefix(start + 10), allUserSplits},
{allSql, keys.MakeTablePrefix(start + 4), keys.MakeTablePrefix(start + 10), allUserSplits[5:]},
{allSql, keys.MakeTablePrefix(start + 5), keys.MakeTablePrefix(start + 10), nil},
{allSql, keys.MakeTablePrefix(start + 6), keys.MakeTablePrefix(start + 10), nil},
{allSql, testutils.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("foo")),
keys.MakeTablePrefix(start + 10), allUserSplits[1:]},
{allSql, testutils.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("foo")),
keys.MakeTablePrefix(start + 5), allUserSplits[1:5]},
{allSql, testutils.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("foo")),
testutils.MakeKey(keys.MakeTablePrefix(start+5), roachpb.RKey("bar")), allUserSplits[1:5]},
{allSql, testutils.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("foo")),
testutils.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("morefoo")), nil},
{allSql, roachpb.RKeyMin, roachpb.RKeyMax, allSplits},
{allSql, keys.MakeTablePrefix(reservedStart + 1), roachpb.RKeyMax, allSplits[2:]},
{allSql, keys.MakeTablePrefix(reservedStart), keys.MakeTablePrefix(start + 10), allSplits[1:]},
{allSql, roachpb.RKeyMin, keys.MakeTablePrefix(start + 2), allSplits[:6]},
{allSql, testutils.MakeKey(keys.MakeTablePrefix(reservedStart), roachpb.RKey("foo")),
testutils.MakeKey(keys.MakeTablePrefix(start+5), roachpb.RKey("foo")), allSplits[1:9]},
}
cfg := config.SystemConfig{}
for tcNum, tc := range testCases {
cfg.Values = tc.values
splits := cfg.ComputeSplitKeys(tc.start, tc.end)
if len(splits) == 0 && len(tc.splits) == 0 {
continue
}
// Convert ints to actual keys.
expected := []roachpb.RKey{}
for _, s := range tc.splits {
expected = append(expected, keys.MakeRowSentinelKey(keys.MakeTablePrefix(s)))
}
if !reflect.DeepEqual(splits, expected) {
t.Errorf("#%d: bad splits:\ngot: %v\nexpected: %v", tcNum, splits, expected)
}
}
}