Fix to make sure all keyrange comparisons go through the key.Package

* We ran into some issues related to padding. This is another form of the bug
fixed in here: https://github.com/vitessio/vitess/pull/8296

Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
This commit is contained in:
Rafael Chacon 2021-09-23 09:35:19 -07:00
Родитель 8bfcf5c9a3
Коммит b06292ffe0
3 изменённых файлов: 69 добавлений и 58 удалений

Просмотреть файл

@ -242,6 +242,14 @@ func KeyRangeStartEqual(left, right *topodatapb.KeyRange) bool {
return bytes.Equal(addPadding(left.Start), addPadding(right.Start))
}
// KeyRangeIsContiguous returns true if left.End equals right.End (i.e they are contigious)
func KeyRangeIsContiguous(left, right *topodatapb.KeyRange) bool {
if left == nil || right == nil {
return false
}
return bytes.Equal(addPadding(left.End), addPadding(right.Start))
}
// KeyRangeEndEqual returns true if both key ranges have the same end
func KeyRangeEndEqual(left, right *topodatapb.KeyRange) bool {
if left == nil {

Просмотреть файл

@ -212,20 +212,6 @@ func TestKeyRangeAdd(t *testing.T) {
out: "40-c0",
ok: true,
}}
stringToKeyRange := func(spec string) *topodatapb.KeyRange {
if spec == "" {
return nil
}
parts := strings.Split(spec, "-")
if len(parts) != 2 {
panic("invalid spec")
}
kr, err := ParseKeyRangeParts(parts[0], parts[1])
if err != nil {
panic(err)
}
return kr
}
keyRangeToString := func(kr *topodatapb.KeyRange) string {
if kr == nil {
return ""
@ -271,20 +257,6 @@ func TestKeyRangeEndEqual(t *testing.T) {
second: "-8000",
out: true,
}}
stringToKeyRange := func(spec string) *topodatapb.KeyRange {
if spec == "" {
return nil
}
parts := strings.Split(spec, "-")
if len(parts) != 2 {
panic("invalid spec")
}
kr, err := ParseKeyRangeParts(parts[0], parts[1])
if err != nil {
panic(err)
}
return kr
}
for _, tcase := range testcases {
first := stringToKeyRange(tcase.first)
@ -326,20 +298,6 @@ func TestKeyRangeStartEqual(t *testing.T) {
second: "-8000",
out: true,
}}
stringToKeyRange := func(spec string) *topodatapb.KeyRange {
if spec == "" {
return nil
}
parts := strings.Split(spec, "-")
if len(parts) != 2 {
panic("invalid spec")
}
kr, err := ParseKeyRangeParts(parts[0], parts[1])
if err != nil {
panic(err)
}
return kr
}
for _, tcase := range testcases {
first := stringToKeyRange(tcase.first)
@ -377,20 +335,6 @@ func TestKeyRangeEqual(t *testing.T) {
second: "-8000",
out: true,
}}
stringToKeyRange := func(spec string) *topodatapb.KeyRange {
if spec == "" {
return nil
}
parts := strings.Split(spec, "-")
if len(parts) != 2 {
panic("invalid spec")
}
kr, err := ParseKeyRangeParts(parts[0], parts[1])
if err != nil {
panic(err)
}
return kr
}
for _, tcase := range testcases {
first := stringToKeyRange(tcase.first)
@ -402,6 +346,51 @@ func TestKeyRangeEqual(t *testing.T) {
}
}
func TestKeyRangeIsContiguous(t *testing.T) {
testcases := []struct {
first string
second string
out bool
}{{
first: "-40",
second: "40-80",
out: true,
}, {
first: "40-80",
second: "-40",
out: false,
}, {
first: "-",
second: "-40",
out: true,
}, {
first: "40-80",
second: "c0-",
out: false,
}, {
first: "40-80",
second: "80-c0",
out: true,
}, {
first: "40-80",
second: "8000000000000000-c000000000000000",
out: true,
}, {
first: "4000000000000000-8000000000000000",
second: "80-c0",
out: true,
}}
for _, tcase := range testcases {
first := stringToKeyRange(tcase.first)
second := stringToKeyRange(tcase.second)
out := KeyRangeIsContiguous(first, second)
if out != tcase.out {
t.Fatalf("KeyRangeEqual(%q, %q) expected %t, got %t", tcase.first, tcase.second, tcase.out, out)
}
}
}
func TestEvenShardsKeyRange_Error(t *testing.T) {
testCases := []struct {
i, n int
@ -815,3 +804,18 @@ func TestShardCalculatorForShardsGreaterThan512(t *testing.T) {
assert.Equal(t, want, got[511], "Invalid mapping for a 512-shard keyspace. Expected %v, got %v", want, got[511])
}
func stringToKeyRange(spec string) *topodatapb.KeyRange {
if spec == "" {
return nil
}
parts := strings.Split(spec, "-")
if len(parts) != 2 {
panic("invalid spec")
}
kr, err := ParseKeyRangeParts(parts[0], parts[1])
if err != nil {
panic(err)
}
return kr
}

Просмотреть файл

@ -17,7 +17,6 @@ limitations under the License.
package topo
import (
"bytes"
"encoding/hex"
"fmt"
"path"
@ -681,7 +680,7 @@ func OrderAndCheckPartitions(cell string, srvKeyspace *topodatapb.SrvKeyspace) e
// this is the custom sharding case, all KeyRanges must be nil
continue
}
if !bytes.Equal(currShard.KeyRange.End, nextShard.KeyRange.Start) {
if !key.KeyRangeIsContiguous(currShard.KeyRange, nextShard.KeyRange) {
return fmt.Errorf("non-contiguous KeyRange values for %v in cell %v at shard %v to %v: %v != %v", tabletType, cell, i, i+1, hex.EncodeToString(currShard.KeyRange.End), hex.EncodeToString(nextShard.KeyRange.Start))
}
}