You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
6.0 KiB
209 lines
6.0 KiB
// Copyright 2018 PingCAP, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package chunk
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/pingcap/check"
|
|
"github.com/pingcap/parser/mysql"
|
|
"github.com/pingcap/tidb/types"
|
|
"github.com/pingcap/tidb/types/json"
|
|
)
|
|
|
|
var _ = check.Suite(&testCodecSuite{})
|
|
|
|
type testCodecSuite struct{}
|
|
|
|
func (s *testCodecSuite) TestCodec(c *check.C) {
|
|
if runtime.Version() >= "go1.14" {
|
|
// TODO: fix https://github.com/pingcap/tidb/issues/15154
|
|
c.Skip("cannot pass checkptr, TODO to fix https://github.com/pingcap/tidb/issues/15154")
|
|
}
|
|
numCols := 6
|
|
numRows := 10
|
|
|
|
colTypes := make([]*types.FieldType, 0, numCols)
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeLonglong})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeLonglong})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeVarchar})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeVarchar})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeNewDecimal})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeJSON})
|
|
|
|
oldChk := NewChunkWithCapacity(colTypes, numRows)
|
|
for i := 0; i < numRows; i++ {
|
|
str := fmt.Sprintf("%d.12345", i)
|
|
oldChk.AppendNull(0)
|
|
oldChk.AppendInt64(1, int64(i))
|
|
oldChk.AppendString(2, str)
|
|
oldChk.AppendString(3, str)
|
|
oldChk.AppendMyDecimal(4, types.NewDecFromStringForTest(str))
|
|
oldChk.AppendJSON(5, json.CreateBinary(str))
|
|
}
|
|
|
|
codec := NewCodec(colTypes)
|
|
buffer := codec.Encode(oldChk)
|
|
|
|
newChk := NewChunkWithCapacity(colTypes, numRows)
|
|
remained := codec.DecodeToChunk(buffer, newChk)
|
|
|
|
c.Assert(len(remained), check.Equals, 0)
|
|
c.Assert(newChk.NumCols(), check.Equals, numCols)
|
|
c.Assert(newChk.NumRows(), check.Equals, numRows)
|
|
for i := 0; i < numRows; i++ {
|
|
row := newChk.GetRow(i)
|
|
str := fmt.Sprintf("%d.12345", i)
|
|
c.Assert(row.IsNull(0), check.IsTrue)
|
|
c.Assert(row.IsNull(1), check.IsFalse)
|
|
c.Assert(row.IsNull(2), check.IsFalse)
|
|
c.Assert(row.IsNull(3), check.IsFalse)
|
|
c.Assert(row.IsNull(4), check.IsFalse)
|
|
c.Assert(row.IsNull(5), check.IsFalse)
|
|
|
|
c.Assert(row.GetInt64(1), check.Equals, int64(i))
|
|
c.Assert(row.GetString(2), check.Equals, str)
|
|
c.Assert(row.GetString(3), check.Equals, str)
|
|
c.Assert(row.GetMyDecimal(4).String(), check.Equals, str)
|
|
c.Assert(string(row.GetJSON(5).GetString()), check.Equals, str)
|
|
}
|
|
}
|
|
|
|
func (s *testCodecSuite) TestEstimateTypeWidth(c *check.C) {
|
|
var colType *types.FieldType
|
|
|
|
colType = &types.FieldType{Tp: mysql.TypeLonglong}
|
|
c.Assert(EstimateTypeWidth(colType), check.Equals, 8) // fixed-witch type
|
|
|
|
colType = &types.FieldType{Tp: mysql.TypeString, Flen: 31}
|
|
c.Assert(EstimateTypeWidth(colType), check.Equals, 31) // colLen <= 32
|
|
|
|
colType = &types.FieldType{Tp: mysql.TypeString, Flen: 999}
|
|
c.Assert(EstimateTypeWidth(colType), check.Equals, 515) // colLen < 1000
|
|
|
|
colType = &types.FieldType{Tp: mysql.TypeString, Flen: 2000}
|
|
c.Assert(EstimateTypeWidth(colType), check.Equals, 516) // colLen < 1000
|
|
|
|
colType = &types.FieldType{Tp: mysql.TypeString}
|
|
c.Assert(EstimateTypeWidth(colType), check.Equals, 32) // value after guessing
|
|
}
|
|
|
|
func BenchmarkEncodeChunk(b *testing.B) {
|
|
numCols := 4
|
|
numRows := 1024
|
|
|
|
chk := &Chunk{columns: make([]*Column, numCols)}
|
|
for i := 0; i < numCols; i++ {
|
|
chk.columns[i] = &Column{
|
|
length: numRows,
|
|
nullBitmap: make([]byte, numRows/8+1),
|
|
data: make([]byte, numRows*8),
|
|
}
|
|
}
|
|
|
|
codec := &Codec{}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
codec.Encode(chk)
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecode(b *testing.B) {
|
|
numCols := 4
|
|
numRows := 1024
|
|
|
|
colTypes := make([]*types.FieldType, numCols)
|
|
chk := &Chunk{columns: make([]*Column, numCols)}
|
|
for i := 0; i < numCols; i++ {
|
|
chk.columns[i] = &Column{
|
|
length: numRows,
|
|
nullBitmap: make([]byte, numRows/8+1),
|
|
data: make([]byte, numRows*8),
|
|
}
|
|
colTypes[i] = &types.FieldType{
|
|
Tp: mysql.TypeLonglong,
|
|
}
|
|
}
|
|
codec := &Codec{colTypes}
|
|
buffer := codec.Encode(chk)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
codec.Decode(buffer)
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeToChunk(b *testing.B) {
|
|
numCols := 4
|
|
numRows := 1024
|
|
|
|
colTypes := make([]*types.FieldType, numCols)
|
|
chk := &Chunk{
|
|
columns: make([]*Column, numCols),
|
|
}
|
|
for i := 0; i < numCols; i++ {
|
|
chk.columns[i] = &Column{
|
|
length: numRows,
|
|
nullBitmap: make([]byte, numRows/8+1),
|
|
data: make([]byte, numRows*8),
|
|
elemBuf: make([]byte, 8),
|
|
}
|
|
colTypes[i] = &types.FieldType{
|
|
Tp: mysql.TypeLonglong,
|
|
}
|
|
}
|
|
codec := &Codec{colTypes}
|
|
buffer := codec.Encode(chk)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
codec.DecodeToChunk(buffer, chk)
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeToChunkWithVariableType(b *testing.B) {
|
|
numCols := 6
|
|
numRows := 1024
|
|
|
|
colTypes := make([]*types.FieldType, 0, numCols)
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeLonglong})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeLonglong})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeVarchar})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeVarchar})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeNewDecimal})
|
|
colTypes = append(colTypes, &types.FieldType{Tp: mysql.TypeJSON})
|
|
|
|
chk := NewChunkWithCapacity(colTypes, numRows)
|
|
for i := 0; i < numRows; i++ {
|
|
str := fmt.Sprintf("%d.12345", i)
|
|
chk.AppendNull(0)
|
|
chk.AppendInt64(1, int64(i))
|
|
chk.AppendString(2, str)
|
|
chk.AppendString(3, str)
|
|
chk.AppendMyDecimal(4, types.NewDecFromStringForTest(str))
|
|
chk.AppendJSON(5, json.CreateBinary(str))
|
|
}
|
|
codec := &Codec{colTypes}
|
|
buffer := codec.Encode(chk)
|
|
|
|
chk.Reset()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
codec.DecodeToChunk(buffer, chk)
|
|
}
|
|
}
|
|
|