*: Update the return value type of CutRow and CutIndexKey to [][]byte (#2978)

This commit is contained in:
Lynn
2017-04-01 18:53:52 +08:00
committed by GitHub
parent aaa6184670
commit 61be27d4ac
6 changed files with 293 additions and 73 deletions

View File

@ -298,7 +298,48 @@ func DecodeRow(b []byte, cols map[int64]*types.FieldType) (map[int64]types.Datum
return row, nil
}
// CutRow cut encoded row into byte slices and return interested columns' byte slice.
// CutRowNew cuts encoded row into byte slices and return columns' byte slice.
// Row layout: colID1, value1, colID2, value2, .....
func CutRowNew(data []byte, colIDs map[int64]int) ([][]byte, error) {
if data == nil {
return nil, nil
}
if len(data) == 1 && data[0] == codec.NilFlag {
return nil, nil
}
var (
cnt int
b []byte
err error
)
row := make([][]byte, len(colIDs))
for len(data) > 0 && cnt < len(colIDs) {
// Get col id.
b, data, err = codec.CutOne(data)
if err != nil {
return nil, errors.Trace(err)
}
_, cid, err := codec.DecodeOne(b)
if err != nil {
return nil, errors.Trace(err)
}
// Get col value.
b, data, err = codec.CutOne(data)
if err != nil {
return nil, errors.Trace(err)
}
id := cid.GetInt64()
offset, ok := colIDs[id]
if ok {
row[offset] = b
cnt++
}
}
return row, nil
}
// CutRow cuts encoded row into byte slices and return interested columns' byte slice.
// Row layout: colID1, value1, colID2, value2, .....
func CutRow(data []byte, cols map[int64]*types.FieldType) (map[int64][]byte, error) {
if data == nil {
@ -421,6 +462,23 @@ func CutIndexKey(key kv.Key, colIDs []int64) (values map[int64][]byte, b []byte,
return
}
// CutIndexKeyNew cuts encoded index key into colIDs to bytes slices.
// The returned value b is the remaining bytes of the key which would be empty if it is unique index or handle data
// if it is non-unique index.
func CutIndexKeyNew(key kv.Key, length int) (values [][]byte, b []byte, err error) {
b = key[prefixLen+idLen:]
values = make([][]byte, 0, length)
for i := 0; i < length; i++ {
var val []byte
val, b, err = codec.CutOne(b)
if err != nil {
return nil, nil, errors.Trace(err)
}
values = append(values, val)
}
return
}
// EncodeTableIndexPrefix encodes index prefix with tableID and idxID.
func EncodeTableIndexPrefix(tableID, idxID int64) kv.Key {
key := make([]byte, 0, prefixLen)

View File

@ -178,6 +178,72 @@ func (s *testTableCodecSuite) TestTimeCodec(c *C) {
}
}
func (s *testTableCodecSuite) TestCutRow(c *C) {
defer testleak.AfterTest(c)()
var err error
c1 := &column{id: 1, tp: types.NewFieldType(mysql.TypeLonglong)}
c2 := &column{id: 2, tp: types.NewFieldType(mysql.TypeVarchar)}
c3 := &column{id: 3, tp: types.NewFieldType(mysql.TypeNewDecimal)}
cols := []*column{c1, c2, c3}
row := make([]types.Datum, 3)
row[0] = types.NewIntDatum(100)
row[1] = types.NewBytesDatum([]byte("abc"))
row[2] = types.NewDecimalDatum(types.NewDecFromInt(1))
data := make([][]byte, 3)
data[0], err = EncodeValue(row[0])
c.Assert(err, IsNil)
data[1], err = EncodeValue(row[1])
c.Assert(err, IsNil)
data[2], err = EncodeValue(row[2])
c.Assert(err, IsNil)
// Encode
colIDs := make([]int64, 0, 3)
for _, col := range cols {
colIDs = append(colIDs, col.id)
}
bs, err := EncodeRow(row, colIDs)
c.Assert(err, IsNil)
c.Assert(bs, NotNil)
// Decode
colMap := make(map[int64]int, 3)
for i, col := range cols {
colMap[col.id] = i
}
r, err := CutRowNew(bs, colMap)
c.Assert(err, IsNil)
c.Assert(r, NotNil)
c.Assert(r, HasLen, 3)
// Compare cut row and original row
for i := range colIDs {
c.Assert(r[i], DeepEquals, data[i])
}
}
func (s *testTableCodecSuite) TestCutKeyNew(c *C) {
values := []types.Datum{types.NewIntDatum(1), types.NewBytesDatum([]byte("abc")), types.NewFloat64Datum(5.5)}
handle := types.NewIntDatum(100)
values = append(values, handle)
encodedValue, err := codec.EncodeKey(nil, values...)
c.Assert(err, IsNil)
tableID := int64(4)
indexID := int64(5)
indexKey := EncodeIndexSeekKey(tableID, indexID, encodedValue)
valuesBytes, handleBytes, err := CutIndexKeyNew(indexKey, 3)
c.Assert(err, IsNil)
for i := 0; i < 3; i++ {
valueBytes := valuesBytes[i]
var val types.Datum
_, val, _ = codec.DecodeOne(valueBytes)
c.Assert(val, DeepEquals, values[i])
}
_, handleVal, _ := codec.DecodeOne(handleBytes)
c.Assert(handleVal, DeepEquals, types.NewIntDatum(100))
}
func (s *testTableCodecSuite) TestCutKey(c *C) {
colIDs := []int64{1, 2, 3}
values := []types.Datum{types.NewIntDatum(1), types.NewBytesDatum([]byte("abc")), types.NewFloat64Datum(5.5)}