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 }