github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/shuffle_test.go (about)

     1  // Copyright 2022 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package plan
    16  
    17  import (
    18  	"bytes"
    19  	"math/rand"
    20  	"testing"
    21  	"unsafe"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/container/types"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  var area = make([]byte, 0, 10000)
    28  
    29  func TestRangeShuffle(t *testing.T) {
    30  	require.Equal(t, GetRangeShuffleIndexUnsignedMinMax(0, 1000000, 299999, 10), uint64(2))
    31  	require.Equal(t, GetRangeShuffleIndexUnsignedMinMax(0, 1000000, 888, 10), uint64(0))
    32  	require.Equal(t, GetRangeShuffleIndexUnsignedMinMax(0, 1000000, 100000000, 10), uint64(9))
    33  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 299999, 10), uint64(2))
    34  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 888, 10), uint64(0))
    35  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 100000000, 10), uint64(9))
    36  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, -2, 10), uint64(0))
    37  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 999000, 10), uint64(9))
    38  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 99999, 10), uint64(0))
    39  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 100000, 10), uint64(1))
    40  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 100001, 10), uint64(1))
    41  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 199999, 10), uint64(1))
    42  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 200000, 10), uint64(2))
    43  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 999999, 10), uint64(9))
    44  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 899999, 10), uint64(8))
    45  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 900000, 10), uint64(9))
    46  	require.Equal(t, GetRangeShuffleIndexSignedMinMax(0, 1000000, 1000000, 10), uint64(9))
    47  }
    48  
    49  func buildVarlenaFromByteSlice(bs []byte) *types.Varlena {
    50  	var v types.Varlena
    51  	vlen := len(bs)
    52  	if vlen <= types.VarlenaInlineSize {
    53  		// first clear varlena to 0
    54  		p1 := v.UnsafePtr()
    55  		*(*int64)(p1) = 0
    56  		*(*int64)(unsafe.Add(p1, 8)) = 0
    57  		*(*int64)(unsafe.Add(p1, 16)) = 0
    58  		v[0] = byte(vlen)
    59  		copy(v[1:1+vlen], bs)
    60  		return &v
    61  	} else {
    62  		voff := len(area)
    63  		area = append(area, bs...)
    64  		v.SetOffsetLen(uint32(voff), uint32(vlen))
    65  	}
    66  	return &v
    67  }
    68  
    69  // The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
    70  func compareUint64(a, b uint64) int {
    71  	if a == b {
    72  		return 0
    73  	} else if a < b {
    74  		return -1
    75  	} else {
    76  		return 1
    77  	}
    78  }
    79  
    80  func TestStringToUint64(t *testing.T) {
    81  	s1 := []byte("abc")
    82  	u1 := VarlenaToUint64Inline(buildVarlenaFromByteSlice(s1))
    83  	require.Equal(t, u1, ByteSliceToUint64(s1))
    84  	s2 := []byte("abcde")
    85  	u2 := VarlenaToUint64Inline(buildVarlenaFromByteSlice(s2))
    86  	require.Equal(t, u2, ByteSliceToUint64(s2))
    87  	s3 := []byte("abcdeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
    88  	u3 := VarlenaToUint64(buildVarlenaFromByteSlice(s3), area)
    89  	require.Equal(t, u3, ByteSliceToUint64(s3))
    90  	s4 := []byte("a")
    91  	u4 := VarlenaToUint64(buildVarlenaFromByteSlice(s4), area)
    92  	require.Equal(t, u4, ByteSliceToUint64(s4))
    93  	s5 := []byte("")
    94  	u5 := VarlenaToUint64(buildVarlenaFromByteSlice(s5), area)
    95  	require.Equal(t, u5, ByteSliceToUint64(s5))
    96  	s6 := []byte("A")
    97  	u6 := VarlenaToUint64(buildVarlenaFromByteSlice(s6), area)
    98  	require.Equal(t, u6, ByteSliceToUint64(s6))
    99  	s7 := []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
   100  	u7 := VarlenaToUint64(buildVarlenaFromByteSlice(s7), area)
   101  	require.Equal(t, u7, ByteSliceToUint64(s7))
   102  
   103  	require.Equal(t, bytes.Compare(s1, s2), compareUint64(u1, u2))
   104  	require.Equal(t, bytes.Compare(s1, s3), compareUint64(u1, u3))
   105  	require.Equal(t, bytes.Compare(s1, s4), compareUint64(u1, u4))
   106  	require.Equal(t, bytes.Compare(s1, s5), compareUint64(u1, u5))
   107  	require.Equal(t, bytes.Compare(s1, s6), compareUint64(u1, u6))
   108  	require.Equal(t, bytes.Compare(s1, s7), compareUint64(u1, u7))
   109  	require.Equal(t, bytes.Compare(s2, s3), compareUint64(u2, u3))
   110  	require.Equal(t, bytes.Compare(s2, s4), compareUint64(u2, u4))
   111  	require.Equal(t, bytes.Compare(s2, s5), compareUint64(u2, u5))
   112  	require.Equal(t, bytes.Compare(s2, s6), compareUint64(u2, u6))
   113  	require.Equal(t, bytes.Compare(s2, s7), compareUint64(u2, u7))
   114  	require.Equal(t, bytes.Compare(s3, s4), compareUint64(u3, u4))
   115  	require.Equal(t, bytes.Compare(s3, s5), compareUint64(u3, u5))
   116  	require.Equal(t, bytes.Compare(s3, s6), compareUint64(u3, u6))
   117  	require.Equal(t, bytes.Compare(s3, s7), compareUint64(u3, u7))
   118  	require.Equal(t, bytes.Compare(s4, s5), compareUint64(u4, u5))
   119  	require.Equal(t, bytes.Compare(s4, s6), compareUint64(u4, u6))
   120  	require.Equal(t, bytes.Compare(s4, s7), compareUint64(u4, u7))
   121  	require.Equal(t, bytes.Compare(s5, s6), compareUint64(u5, u6))
   122  	require.Equal(t, bytes.Compare(s5, s7), compareUint64(u5, u7))
   123  	require.Equal(t, bytes.Compare(s6, s7), compareUint64(u6, u7))
   124  }
   125  
   126  type ShuffleRangeTestCase struct {
   127  	min []float64
   128  	max []float64
   129  }
   130  
   131  func TestShuffleRange(t *testing.T) {
   132  	testcase := make([]ShuffleRangeTestCase, 0)
   133  	testcase = append(testcase, ShuffleRangeTestCase{
   134  		min: []float64{},
   135  		max: []float64{},
   136  	})
   137  	testcase[0].min = append(testcase[0].min, 0)
   138  	testcase[0].max = append(testcase[0].max, 10000)
   139  	for i := 1; i < 100000; i++ {
   140  		testcase[0].min = append(testcase[0].min, testcase[0].max[i-1]+float64(rand.Int()%10000))
   141  		testcase[0].max = append(testcase[0].max, testcase[0].min[i]+float64(rand.Int()%10000+100))
   142  	}
   143  	testcase[0].min = append(testcase[0].min, testcase[0].max[99999]/2)
   144  	testcase[0].max = append(testcase[0].max, testcase[0].min[100000]+10000)
   145  	for i := 100001; i <= 200000; i++ {
   146  		testcase[0].min = append(testcase[0].min, testcase[0].max[i-1]+float64(rand.Int()%10000))
   147  		testcase[0].max = append(testcase[0].max, testcase[0].min[i]+float64(rand.Int()%10000+100))
   148  	}
   149  
   150  	testcase = append(testcase, ShuffleRangeTestCase{
   151  		min: []float64{},
   152  		max: []float64{},
   153  	})
   154  	for i := 0; i <= 100000; i++ {
   155  		testcase[1].min = append(testcase[1].min, float64(rand.Int()))
   156  		testcase[1].max = append(testcase[1].max, testcase[1].min[i]+float64(rand.Int()))
   157  	}
   158  
   159  	testcase = append(testcase, ShuffleRangeTestCase{
   160  		min: []float64{},
   161  		max: []float64{},
   162  	})
   163  	testcase[2].min = append(testcase[2].min, 0)
   164  	testcase[2].max = append(testcase[2].max, 10000)
   165  	for i := 1; i < 100000; i++ {
   166  		testcase[2].min = append(testcase[2].min, testcase[2].max[i-1]-10)
   167  		testcase[2].max = append(testcase[2].max, testcase[2].min[i]+10000)
   168  	}
   169  
   170  	leng := len(testcase)
   171  
   172  	for i := 0; i < leng; i++ {
   173  		shufflerange := NewShuffleRange(false)
   174  		for j := 0; j < len(testcase[i].min); j++ {
   175  			shufflerange.Update(testcase[i].min[j], testcase[i].max[j], 1000, 1)
   176  		}
   177  		shufflerange.Eval()
   178  	}
   179  	shufflerange := NewShuffleRange(true)
   180  	shufflerange.UpdateString([]byte("0000"), []byte("1000"), 1000, 1)
   181  	shufflerange.UpdateString([]byte("2000"), []byte("3000"), 1000, 1)
   182  	shufflerange.UpdateString([]byte("4000"), []byte("5000"), 1000, 1)
   183  	shufflerange.UpdateString([]byte("6000"), []byte("7000"), 1000, 1)
   184  	shufflerange.UpdateString([]byte("8000"), []byte("9000"), 1000, 1)
   185  	shufflerange.Eval()
   186  }
   187  
   188  func TestRangeShuffleSlice(t *testing.T) {
   189  	require.Equal(t, GetRangeShuffleIndexSignedSlice([]int64{1, 3, 5, 7, 9}, 5), uint64(2))
   190  	require.Equal(t, GetRangeShuffleIndexSignedSlice([]int64{1, 2, 3, 100}, 101), uint64(4))
   191  	require.Equal(t, GetRangeShuffleIndexSignedSlice([]int64{-20, -1, 0, 1, 5}, -99), uint64(0))
   192  	require.Equal(t, GetRangeShuffleIndexUnsignedSlice([]uint64{100, 200, 300}, 150), uint64(1))
   193  	require.Equal(t, GetRangeShuffleIndexUnsignedSlice([]uint64{10001, 10002, 10003, 10004, 10005, 10006}, 10006), uint64(5))
   194  	require.Equal(t, GetRangeShuffleIndexUnsignedSlice([]uint64{30, 50, 60, 90, 120}, 61), uint64(3))
   195  }