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  }