github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/soliton/chunk/codec_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, 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 chunk
    15  
    16  import (
    17  	"fmt"
    18  	"runtime"
    19  	"testing"
    20  
    21  	"github.com/whtcorpsinc/check"
    22  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    23  	"github.com/whtcorpsinc/milevadb/types"
    24  	"github.com/whtcorpsinc/milevadb/types/json"
    25  )
    26  
    27  var _ = check.Suite(&testCodecSuite{})
    28  
    29  type testCodecSuite struct{}
    30  
    31  func (s *testCodecSuite) TestCodec(c *check.C) {
    32  	if runtime.Version() >= "go1.14" {
    33  		// TODO: fix https://github.com/whtcorpsinc/milevadb/issues/15154
    34  		c.Skip("cannot pass checkptr, TODO to fix https://github.com/whtcorpsinc/milevadb/issues/15154")
    35  	}
    36  	numDefCauss := 6
    37  	numRows := 10
    38  
    39  	defCausTypes := make([]*types.FieldType, 0, numDefCauss)
    40  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeLonglong})
    41  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeLonglong})
    42  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeVarchar})
    43  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeVarchar})
    44  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeNewDecimal})
    45  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeJSON})
    46  
    47  	oldChk := NewChunkWithCapacity(defCausTypes, numRows)
    48  	for i := 0; i < numRows; i++ {
    49  		str := fmt.Sprintf("%d.12345", i)
    50  		oldChk.AppendNull(0)
    51  		oldChk.AppendInt64(1, int64(i))
    52  		oldChk.AppendString(2, str)
    53  		oldChk.AppendString(3, str)
    54  		oldChk.AppendMyDecimal(4, types.NewDecFromStringForTest(str))
    55  		oldChk.AppendJSON(5, json.CreateBinary(str))
    56  	}
    57  
    58  	codec := NewCodec(defCausTypes)
    59  	buffer := codec.Encode(oldChk)
    60  
    61  	newChk := NewChunkWithCapacity(defCausTypes, numRows)
    62  	remained := codec.DecodeToChunk(buffer, newChk)
    63  
    64  	c.Assert(len(remained), check.Equals, 0)
    65  	c.Assert(newChk.NumDefCauss(), check.Equals, numDefCauss)
    66  	c.Assert(newChk.NumRows(), check.Equals, numRows)
    67  	for i := 0; i < numRows; i++ {
    68  		event := newChk.GetRow(i)
    69  		str := fmt.Sprintf("%d.12345", i)
    70  		c.Assert(event.IsNull(0), check.IsTrue)
    71  		c.Assert(event.IsNull(1), check.IsFalse)
    72  		c.Assert(event.IsNull(2), check.IsFalse)
    73  		c.Assert(event.IsNull(3), check.IsFalse)
    74  		c.Assert(event.IsNull(4), check.IsFalse)
    75  		c.Assert(event.IsNull(5), check.IsFalse)
    76  
    77  		c.Assert(event.GetInt64(1), check.Equals, int64(i))
    78  		c.Assert(event.GetString(2), check.Equals, str)
    79  		c.Assert(event.GetString(3), check.Equals, str)
    80  		c.Assert(event.GetMyDecimal(4).String(), check.Equals, str)
    81  		c.Assert(string(event.GetJSON(5).GetString()), check.Equals, str)
    82  	}
    83  }
    84  
    85  func (s *testCodecSuite) TestEstimateTypeWidth(c *check.C) {
    86  	var defCausType *types.FieldType
    87  
    88  	defCausType = &types.FieldType{Tp: allegrosql.TypeLonglong}
    89  	c.Assert(EstimateTypeWidth(defCausType), check.Equals, 8) // fixed-witch type
    90  
    91  	defCausType = &types.FieldType{Tp: allegrosql.TypeString, Flen: 31}
    92  	c.Assert(EstimateTypeWidth(defCausType), check.Equals, 31) // defCausLen <= 32
    93  
    94  	defCausType = &types.FieldType{Tp: allegrosql.TypeString, Flen: 999}
    95  	c.Assert(EstimateTypeWidth(defCausType), check.Equals, 515) // defCausLen < 1000
    96  
    97  	defCausType = &types.FieldType{Tp: allegrosql.TypeString, Flen: 2000}
    98  	c.Assert(EstimateTypeWidth(defCausType), check.Equals, 516) // defCausLen < 1000
    99  
   100  	defCausType = &types.FieldType{Tp: allegrosql.TypeString}
   101  	c.Assert(EstimateTypeWidth(defCausType), check.Equals, 32) // value after guessing
   102  }
   103  
   104  func BenchmarkEncodeChunk(b *testing.B) {
   105  	numDefCauss := 4
   106  	numRows := 1024
   107  
   108  	chk := &Chunk{defCausumns: make([]*DeferredCauset, numDefCauss)}
   109  	for i := 0; i < numDefCauss; i++ {
   110  		chk.defCausumns[i] = &DeferredCauset{
   111  			length:     numRows,
   112  			nullBitmap: make([]byte, numRows/8+1),
   113  			data:       make([]byte, numRows*8),
   114  		}
   115  	}
   116  
   117  	codec := &Codec{}
   118  
   119  	b.ResetTimer()
   120  	for i := 0; i < b.N; i++ {
   121  		codec.Encode(chk)
   122  	}
   123  }
   124  
   125  func BenchmarkDecode(b *testing.B) {
   126  	numDefCauss := 4
   127  	numRows := 1024
   128  
   129  	defCausTypes := make([]*types.FieldType, numDefCauss)
   130  	chk := &Chunk{defCausumns: make([]*DeferredCauset, numDefCauss)}
   131  	for i := 0; i < numDefCauss; i++ {
   132  		chk.defCausumns[i] = &DeferredCauset{
   133  			length:     numRows,
   134  			nullBitmap: make([]byte, numRows/8+1),
   135  			data:       make([]byte, numRows*8),
   136  		}
   137  		defCausTypes[i] = &types.FieldType{
   138  			Tp: allegrosql.TypeLonglong,
   139  		}
   140  	}
   141  	codec := &Codec{defCausTypes}
   142  	buffer := codec.Encode(chk)
   143  
   144  	b.ResetTimer()
   145  	for i := 0; i < b.N; i++ {
   146  		codec.Decode(buffer)
   147  	}
   148  }
   149  
   150  func BenchmarkDecodeToChunk(b *testing.B) {
   151  	numDefCauss := 4
   152  	numRows := 1024
   153  
   154  	defCausTypes := make([]*types.FieldType, numDefCauss)
   155  	chk := &Chunk{
   156  		defCausumns: make([]*DeferredCauset, numDefCauss),
   157  	}
   158  	for i := 0; i < numDefCauss; i++ {
   159  		chk.defCausumns[i] = &DeferredCauset{
   160  			length:     numRows,
   161  			nullBitmap: make([]byte, numRows/8+1),
   162  			data:       make([]byte, numRows*8),
   163  			elemBuf:    make([]byte, 8),
   164  		}
   165  		defCausTypes[i] = &types.FieldType{
   166  			Tp: allegrosql.TypeLonglong,
   167  		}
   168  	}
   169  	codec := &Codec{defCausTypes}
   170  	buffer := codec.Encode(chk)
   171  
   172  	b.ResetTimer()
   173  	for i := 0; i < b.N; i++ {
   174  		codec.DecodeToChunk(buffer, chk)
   175  	}
   176  }
   177  
   178  func BenchmarkDecodeToChunkWithVariableType(b *testing.B) {
   179  	numDefCauss := 6
   180  	numRows := 1024
   181  
   182  	defCausTypes := make([]*types.FieldType, 0, numDefCauss)
   183  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeLonglong})
   184  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeLonglong})
   185  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeVarchar})
   186  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeVarchar})
   187  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeNewDecimal})
   188  	defCausTypes = append(defCausTypes, &types.FieldType{Tp: allegrosql.TypeJSON})
   189  
   190  	chk := NewChunkWithCapacity(defCausTypes, numRows)
   191  	for i := 0; i < numRows; i++ {
   192  		str := fmt.Sprintf("%d.12345", i)
   193  		chk.AppendNull(0)
   194  		chk.AppendInt64(1, int64(i))
   195  		chk.AppendString(2, str)
   196  		chk.AppendString(3, str)
   197  		chk.AppendMyDecimal(4, types.NewDecFromStringForTest(str))
   198  		chk.AppendJSON(5, json.CreateBinary(str))
   199  	}
   200  	codec := &Codec{defCausTypes}
   201  	buffer := codec.Encode(chk)
   202  
   203  	chk.Reset()
   204  
   205  	b.ResetTimer()
   206  	for i := 0; i < b.N; i++ {
   207  		codec.DecodeToChunk(buffer, chk)
   208  	}
   209  }