github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/pkg/util/overlap_merge_test.go (about) 1 // Copyright 2020 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package util 15 16 import ( 17 "bytes" 18 "fmt" 19 20 "github.com/pingcap/check" 21 "github.com/pingcap/ticdc/pkg/util/testleak" 22 ) 23 24 type overlapSuite struct{} 25 26 var _ = check.Suite(&overlapSuite{}) 27 28 func (s *overlapSuite) TestOverlapCoveringMerge(c *check.C) { 29 defer testleak.AfterTest(c)() 30 tests := []struct { 31 name string 32 // inputs is a slice of coverings. The inner slice represents a covering 33 // as an even number of ints, which are pairwise endpoints. So (1, 2, 2, 34 // 4) means [/1, /2) and [/2, /4). 35 inputs [][]byte 36 // expectedIntervals is the output ranges in the same format as an input 37 // covering. 38 expectedIntervals []byte 39 // expectedPayloads is the output payloads, corresponding 1:1 with 40 // entries in expectedIntervals. Each input range is given an int 41 // payload from 0..N-1 where N is the total number of ranges in all 42 // input coverings for this test. Each of these is formatted as a string 43 // concatenation of these ints. 44 // 45 // So for covering [1, 2), [2, 3) and covering [1, 3), the output 46 // payloads would be "02" for [1, 2) and "12" for [2, 3). 47 expectedPayloads []string 48 }{ 49 { 50 "no input", 51 [][]byte{}, 52 nil, nil, 53 }, 54 { 55 "one empty covering", 56 [][]byte{{}}, 57 nil, nil, 58 }, 59 { 60 "two empty coverings", 61 [][]byte{{}, {}}, 62 nil, nil, 63 }, 64 { 65 "one", 66 [][]byte{{1, 2}, {}}, 67 []byte{1, 2}, 68 []string{"0"}, 69 }, 70 { 71 "same", 72 [][]byte{{1, 2}, {1, 2}}, 73 []byte{1, 2}, 74 []string{"01"}, 75 }, 76 { 77 "overlap", 78 [][]byte{{1, 3}, {2, 3}}, 79 []byte{1, 2, 2, 3}, 80 []string{"0", "01"}, 81 }, 82 { 83 "overlap reversed", 84 [][]byte{{2, 3}, {1, 3}}, 85 []byte{1, 2, 2, 3}, 86 []string{"1", "01"}, 87 }, 88 { 89 "no overlap", 90 [][]byte{{1, 2, 5, 6}, {3, 4}}, 91 []byte{1, 2, 3, 4, 5, 6}, 92 []string{"0", "2", "1"}, 93 }, 94 { 95 "range splits and merges", 96 [][]byte{{1, 3, 3, 4}, {1, 4}, {1, 2, 2, 4}}, 97 []byte{1, 2, 2, 3, 3, 4}, 98 []string{"023", "024", "124"}, 99 }, 100 { 101 "godoc example", 102 [][]byte{{1, 2, 3, 4, 6, 7}, {1, 5}}, 103 []byte{1, 2, 2, 3, 3, 4, 4, 5, 6, 7}, 104 []string{"03", "3", "13", "3", "2"}, 105 }, 106 { 107 "empty", 108 [][]byte{{1, 2, 2, 2, 2, 2, 4, 5}, {1, 5}}, 109 []byte{1, 2, 2, 2, 2, 4, 4, 5}, 110 []string{"04", "124", "4", "34"}, 111 }, 112 } 113 114 for _, test := range tests { 115 c.Log("test: ", test.name) 116 117 var payload int 118 var inputs []Covering 119 for _, endpoints := range test.inputs { 120 var c Covering 121 for i := 0; i < len(endpoints); i += 2 { 122 c = append(c, Range{ 123 Start: []byte{endpoints[i]}, 124 End: []byte{endpoints[i+1]}, 125 Payload: payload, 126 }) 127 payload++ 128 } 129 inputs = append(inputs, c) 130 } 131 var outputIntervals []byte 132 var outputPayloads []string 133 for _, r := range OverlapCoveringMerge(inputs) { 134 outputIntervals = append(outputIntervals, r.Start[0], r.End[0]) 135 var payload bytes.Buffer 136 for _, p := range r.Payload.([]interface{}) { 137 fmt.Fprintf(&payload, "%d", p.(int)) 138 } 139 outputPayloads = append(outputPayloads, payload.String()) 140 } 141 142 c.Assert(outputIntervals, check.DeepEquals, test.expectedIntervals) 143 c.Assert(outputPayloads, check.DeepEquals, test.expectedPayloads) 144 } 145 }