github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/chunk/column.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  	"math/bits"
    19  	"reflect"
    20  	"time"
    21  	"unsafe"
    22  
    23  	"github.com/whtcorpsinc/milevadb/types"
    24  	"github.com/whtcorpsinc/milevadb/types/json"
    25  	"github.com/whtcorpsinc/milevadb/soliton/replog"
    26  )
    27  
    28  // AppendDuration appends a duration value into this DeferredCauset.
    29  func (c *DeferredCauset) AppendDuration(dur types.Duration) {
    30  	c.AppendInt64(int64(dur.Duration))
    31  }
    32  
    33  // AppendMyDecimal appends a MyDecimal value into this DeferredCauset.
    34  func (c *DeferredCauset) AppendMyDecimal(dec *types.MyDecimal) {
    35  	*(*types.MyDecimal)(unsafe.Pointer(&c.elemBuf[0])) = *dec
    36  	c.finishAppendFixed()
    37  }
    38  
    39  func (c *DeferredCauset) appendNameValue(name string, val uint64) {
    40  	var buf [8]byte
    41  	copy(buf[:], (*[8]byte)(unsafe.Pointer(&val))[:])
    42  	c.data = append(c.data, buf[:]...)
    43  	c.data = append(c.data, name...)
    44  	c.finishAppendVar()
    45  }
    46  
    47  // AppendJSON appends a BinaryJSON value into this DeferredCauset.
    48  func (c *DeferredCauset) AppendJSON(j json.BinaryJSON) {
    49  	c.data = append(c.data, j.TypeCode)
    50  	c.data = append(c.data, j.Value...)
    51  	c.finishAppendVar()
    52  }
    53  
    54  // AppendSet appends a Set value into this DeferredCauset.
    55  func (c *DeferredCauset) AppendSet(set types.Set) {
    56  	c.appendNameValue(set.Name, set.Value)
    57  }
    58  
    59  // DeferredCauset stores one defCausumn of data in Apache Arrow format.
    60  // See https://arrow.apache.org/docs/memory_layout.html
    61  type DeferredCauset struct {
    62  	length     int
    63  	nullBitmap []byte // bit 0 is null, 1 is not null
    64  	offsets    []int64
    65  	data       []byte
    66  	elemBuf    []byte
    67  }
    68  
    69  // NewDeferredCauset creates a new defCausumn with the specific length and capacity.
    70  func NewDeferredCauset(ft *types.FieldType, cap int) *DeferredCauset {
    71  	return newDeferredCauset(getFixedLen(ft), cap)
    72  }
    73  
    74  func newDeferredCauset(typeSize, cap int) *DeferredCauset {
    75  	var defCaus *DeferredCauset
    76  	if typeSize == varElemLen {
    77  		defCaus = newVarLenDeferredCauset(cap, nil)
    78  	} else {
    79  		defCaus = newFixedLenDeferredCauset(typeSize, cap)
    80  	}
    81  	return defCaus
    82  }
    83  
    84  func (c *DeferredCauset) typeSize() int {
    85  	if len(c.elemBuf) > 0 {
    86  		return len(c.elemBuf)
    87  	}
    88  	return varElemLen
    89  }
    90  
    91  func (c *DeferredCauset) isFixed() bool {
    92  	return c.elemBuf != nil
    93  }
    94  
    95  // Reset resets this DeferredCauset according to the EvalType.
    96  // Different from reset, Reset will reset the elemBuf.
    97  func (c *DeferredCauset) Reset(eType types.EvalType) {
    98  	switch eType {
    99  	case types.ETInt:
   100  		c.ResizeInt64(0, false)
   101  	case types.ETReal:
   102  		c.ResizeFloat64(0, false)
   103  	case types.ETDecimal:
   104  		c.ResizeDecimal(0, false)
   105  	case types.ETString:
   106  		c.ReserveString(0)
   107  	case types.ETDatetime, types.ETTimestamp:
   108  		c.ResizeTime(0, false)
   109  	case types.ETDuration:
   110  		c.ResizeGoDuration(0, false)
   111  	case types.ETJson:
   112  		c.ReserveJSON(0)
   113  	default:
   114  		panic(fmt.Sprintf("invalid EvalType %v", eType))
   115  	}
   116  }
   117  
   118  // reset resets the underlying data of this DeferredCauset but doesn't modify its data type.
   119  func (c *DeferredCauset) reset() {
   120  	c.length = 0
   121  	c.nullBitmap = c.nullBitmap[:0]
   122  	if len(c.offsets) > 0 {
   123  		// The first offset is always 0, it makes slicing the data easier, we need to keep it.
   124  		c.offsets = c.offsets[:1]
   125  	}
   126  	c.data = c.data[:0]
   127  }
   128  
   129  // IsNull returns if this event is null.
   130  func (c *DeferredCauset) IsNull(rowIdx int) bool {
   131  	nullByte := c.nullBitmap[rowIdx/8]
   132  	return nullByte&(1<<(uint(rowIdx)&7)) == 0
   133  }
   134  
   135  // CopyConstruct copies this DeferredCauset to dst.
   136  // If dst is nil, it creates a new DeferredCauset and returns it.
   137  func (c *DeferredCauset) CopyConstruct(dst *DeferredCauset) *DeferredCauset {
   138  	if dst != nil {
   139  		dst.length = c.length
   140  		dst.nullBitmap = append(dst.nullBitmap[:0], c.nullBitmap...)
   141  		dst.offsets = append(dst.offsets[:0], c.offsets...)
   142  		dst.data = append(dst.data[:0], c.data...)
   143  		dst.elemBuf = append(dst.elemBuf[:0], c.elemBuf...)
   144  		return dst
   145  	}
   146  	newDefCaus := &DeferredCauset{length: c.length}
   147  	newDefCaus.nullBitmap = append(newDefCaus.nullBitmap, c.nullBitmap...)
   148  	newDefCaus.offsets = append(newDefCaus.offsets, c.offsets...)
   149  	newDefCaus.data = append(newDefCaus.data, c.data...)
   150  	newDefCaus.elemBuf = append(newDefCaus.elemBuf, c.elemBuf...)
   151  	return newDefCaus
   152  }
   153  
   154  func (c *DeferredCauset) appendNullBitmap(notNull bool) {
   155  	idx := c.length >> 3
   156  	if idx >= len(c.nullBitmap) {
   157  		c.nullBitmap = append(c.nullBitmap, 0)
   158  	}
   159  	if notNull {
   160  		pos := uint(c.length) & 7
   161  		c.nullBitmap[idx] |= byte(1 << pos)
   162  	}
   163  }
   164  
   165  // appendMultiSameNullBitmap appends multiple same bit value to `nullBitMap`.
   166  // notNull means not null.
   167  // num means the number of bits that should be appended.
   168  func (c *DeferredCauset) appendMultiSameNullBitmap(notNull bool, num int) {
   169  	numNewBytes := ((c.length + num + 7) >> 3) - len(c.nullBitmap)
   170  	b := byte(0)
   171  	if notNull {
   172  		b = 0xff
   173  	}
   174  	for i := 0; i < numNewBytes; i++ {
   175  		c.nullBitmap = append(c.nullBitmap, b)
   176  	}
   177  	if !notNull {
   178  		return
   179  	}
   180  	// 1. Set all the remaining bits in the last slot of old c.numBitMap to 1.
   181  	numRemainingBits := uint(c.length % 8)
   182  	bitMask := byte(^((1 << numRemainingBits) - 1))
   183  	c.nullBitmap[c.length/8] |= bitMask
   184  	// 2. Set all the redundant bits in the last slot of new c.numBitMap to 0.
   185  	numRedundantBits := uint(len(c.nullBitmap)*8 - c.length - num)
   186  	bitMask = byte(1<<(8-numRedundantBits)) - 1
   187  	c.nullBitmap[len(c.nullBitmap)-1] &= bitMask
   188  }
   189  
   190  // AppendNull appends a null value into this DeferredCauset.
   191  func (c *DeferredCauset) AppendNull() {
   192  	c.appendNullBitmap(false)
   193  	if c.isFixed() {
   194  		c.data = append(c.data, c.elemBuf...)
   195  	} else {
   196  		c.offsets = append(c.offsets, c.offsets[c.length])
   197  	}
   198  	c.length++
   199  }
   200  
   201  func (c *DeferredCauset) finishAppendFixed() {
   202  	c.data = append(c.data, c.elemBuf...)
   203  	c.appendNullBitmap(true)
   204  	c.length++
   205  }
   206  
   207  // AppendInt64 appends an int64 value into this DeferredCauset.
   208  func (c *DeferredCauset) AppendInt64(i int64) {
   209  	*(*int64)(unsafe.Pointer(&c.elemBuf[0])) = i
   210  	c.finishAppendFixed()
   211  }
   212  
   213  // AppendUint64 appends a uint64 value into this DeferredCauset.
   214  func (c *DeferredCauset) AppendUint64(u uint64) {
   215  	*(*uint64)(unsafe.Pointer(&c.elemBuf[0])) = u
   216  	c.finishAppendFixed()
   217  }
   218  
   219  // AppendFloat32 appends a float32 value into this DeferredCauset.
   220  func (c *DeferredCauset) AppendFloat32(f float32) {
   221  	*(*float32)(unsafe.Pointer(&c.elemBuf[0])) = f
   222  	c.finishAppendFixed()
   223  }
   224  
   225  // AppendFloat64 appends a float64 value into this DeferredCauset.
   226  func (c *DeferredCauset) AppendFloat64(f float64) {
   227  	*(*float64)(unsafe.Pointer(&c.elemBuf[0])) = f
   228  	c.finishAppendFixed()
   229  }
   230  
   231  func (c *DeferredCauset) finishAppendVar() {
   232  	c.appendNullBitmap(true)
   233  	c.offsets = append(c.offsets, int64(len(c.data)))
   234  	c.length++
   235  }
   236  
   237  // AppendString appends a string value into this DeferredCauset.
   238  func (c *DeferredCauset) AppendString(str string) {
   239  	c.data = append(c.data, str...)
   240  	c.finishAppendVar()
   241  }
   242  
   243  // AppendBytes appends a byte slice into this DeferredCauset.
   244  func (c *DeferredCauset) AppendBytes(b []byte) {
   245  	c.data = append(c.data, b...)
   246  	c.finishAppendVar()
   247  }
   248  
   249  // AppendTime appends a time value into this DeferredCauset.
   250  func (c *DeferredCauset) AppendTime(t types.Time) {
   251  	*(*types.Time)(unsafe.Pointer(&c.elemBuf[0])) = t
   252  	c.finishAppendFixed()
   253  }
   254  
   255  // AppendEnum appends a Enum value into this DeferredCauset.
   256  func (c *DeferredCauset) AppendEnum(enum types.Enum) {
   257  	c.appendNameValue(enum.Name, enum.Value)
   258  }
   259  
   260  const (
   261  	sizeInt64      = int(unsafe.Sizeof(int64(0)))
   262  	sizeUint64     = int(unsafe.Sizeof(uint64(0)))
   263  	sizeFloat32    = int(unsafe.Sizeof(float32(0)))
   264  	sizeFloat64    = int(unsafe.Sizeof(float64(0)))
   265  	sizeMyDecimal  = int(unsafe.Sizeof(types.MyDecimal{}))
   266  	sizeGoDuration = int(unsafe.Sizeof(time.Duration(0)))
   267  	sizeTime       = int(unsafe.Sizeof(types.ZeroTime))
   268  )
   269  
   270  var (
   271  	emptyBuf = make([]byte, 4*1024)
   272  )
   273  
   274  // resize resizes the defCausumn so that it contains n elements, only valid for fixed-length types.
   275  func (c *DeferredCauset) resize(n, typeSize int, isNull bool) {
   276  	sizeData := n * typeSize
   277  	if cap(c.data) >= sizeData {
   278  		(*reflect.SliceHeader)(unsafe.Pointer(&c.data)).Len = sizeData
   279  	} else {
   280  		c.data = make([]byte, sizeData)
   281  	}
   282  	if !isNull {
   283  		for j := 0; j < sizeData; j += len(emptyBuf) {
   284  			copy(c.data[j:], emptyBuf)
   285  		}
   286  	}
   287  
   288  	newNulls := false
   289  	sizeNulls := (n + 7) >> 3
   290  	if cap(c.nullBitmap) >= sizeNulls {
   291  		(*reflect.SliceHeader)(unsafe.Pointer(&c.nullBitmap)).Len = sizeNulls
   292  	} else {
   293  		c.nullBitmap = make([]byte, sizeNulls)
   294  		newNulls = true
   295  	}
   296  	if !isNull || !newNulls {
   297  		var nullVal byte
   298  		if !isNull {
   299  			nullVal = 0xFF
   300  		}
   301  		for i := range c.nullBitmap {
   302  			c.nullBitmap[i] = nullVal
   303  		}
   304  	}
   305  
   306  	if cap(c.elemBuf) >= typeSize {
   307  		(*reflect.SliceHeader)(unsafe.Pointer(&c.elemBuf)).Len = typeSize
   308  	} else {
   309  		c.elemBuf = make([]byte, typeSize)
   310  	}
   311  
   312  	c.length = n
   313  }
   314  
   315  // reserve makes the defCausumn capacity be at least enough to contain n elements.
   316  // this method is only valid for var-length types and estElemSize is the estimated size of this type.
   317  func (c *DeferredCauset) reserve(n, estElemSize int) {
   318  	sizeData := n * estElemSize
   319  	if cap(c.data) >= sizeData {
   320  		c.data = c.data[:0]
   321  	} else {
   322  		c.data = make([]byte, 0, sizeData)
   323  	}
   324  
   325  	sizeNulls := (n + 7) >> 3
   326  	if cap(c.nullBitmap) >= sizeNulls {
   327  		c.nullBitmap = c.nullBitmap[:0]
   328  	} else {
   329  		c.nullBitmap = make([]byte, 0, sizeNulls)
   330  	}
   331  
   332  	sizeOffs := n + 1
   333  	if cap(c.offsets) >= sizeOffs {
   334  		c.offsets = c.offsets[:1]
   335  	} else {
   336  		c.offsets = make([]int64, 1, sizeOffs)
   337  	}
   338  
   339  	c.elemBuf = nil
   340  	c.length = 0
   341  }
   342  
   343  // SetNull sets the rowIdx to null.
   344  func (c *DeferredCauset) SetNull(rowIdx int, isNull bool) {
   345  	if isNull {
   346  		c.nullBitmap[rowIdx>>3] &= ^(1 << uint(rowIdx&7))
   347  	} else {
   348  		c.nullBitmap[rowIdx>>3] |= 1 << uint(rowIdx&7)
   349  	}
   350  }
   351  
   352  // SetNulls sets rows in [begin, end) to null.
   353  func (c *DeferredCauset) SetNulls(begin, end int, isNull bool) {
   354  	i := ((begin + 7) >> 3) << 3
   355  	for ; begin < i && begin < end; begin++ {
   356  		c.SetNull(begin, isNull)
   357  	}
   358  	var v uint8
   359  	if !isNull {
   360  		v = (1 << 8) - 1
   361  	}
   362  	for ; begin+8 <= end; begin += 8 {
   363  		c.nullBitmap[begin>>3] = v
   364  	}
   365  	for ; begin < end; begin++ {
   366  		c.SetNull(begin, isNull)
   367  	}
   368  }
   369  
   370  // nullCount returns the number of nulls in this DeferredCauset.
   371  func (c *DeferredCauset) nullCount() int {
   372  	var cnt, i int
   373  	for ; i+8 <= c.length; i += 8 {
   374  		// 0 is null and 1 is not null
   375  		cnt += 8 - bits.OnesCount8(c.nullBitmap[i>>3])
   376  	}
   377  	for ; i < c.length; i++ {
   378  		if c.IsNull(i) {
   379  			cnt++
   380  		}
   381  	}
   382  	return cnt
   383  }
   384  
   385  // ResizeInt64 resizes the defCausumn so that it contains n int64 elements.
   386  func (c *DeferredCauset) ResizeInt64(n int, isNull bool) {
   387  	c.resize(n, sizeInt64, isNull)
   388  }
   389  
   390  // ResizeUint64 resizes the defCausumn so that it contains n uint64 elements.
   391  func (c *DeferredCauset) ResizeUint64(n int, isNull bool) {
   392  	c.resize(n, sizeUint64, isNull)
   393  }
   394  
   395  // ResizeFloat32 resizes the defCausumn so that it contains n float32 elements.
   396  func (c *DeferredCauset) ResizeFloat32(n int, isNull bool) {
   397  	c.resize(n, sizeFloat32, isNull)
   398  }
   399  
   400  // ResizeFloat64 resizes the defCausumn so that it contains n float64 elements.
   401  func (c *DeferredCauset) ResizeFloat64(n int, isNull bool) {
   402  	c.resize(n, sizeFloat64, isNull)
   403  }
   404  
   405  // ResizeDecimal resizes the defCausumn so that it contains n decimal elements.
   406  func (c *DeferredCauset) ResizeDecimal(n int, isNull bool) {
   407  	c.resize(n, sizeMyDecimal, isNull)
   408  }
   409  
   410  // ResizeGoDuration resizes the defCausumn so that it contains n duration elements.
   411  func (c *DeferredCauset) ResizeGoDuration(n int, isNull bool) {
   412  	c.resize(n, sizeGoDuration, isNull)
   413  }
   414  
   415  // ResizeTime resizes the defCausumn so that it contains n Time elements.
   416  func (c *DeferredCauset) ResizeTime(n int, isNull bool) {
   417  	c.resize(n, sizeTime, isNull)
   418  }
   419  
   420  // ReserveString changes the defCausumn capacity to causetstore n string elements and set the length to zero.
   421  func (c *DeferredCauset) ReserveString(n int) {
   422  	c.reserve(n, 8)
   423  }
   424  
   425  // ReserveBytes changes the defCausumn capacity to causetstore n bytes elements and set the length to zero.
   426  func (c *DeferredCauset) ReserveBytes(n int) {
   427  	c.reserve(n, 8)
   428  }
   429  
   430  // ReserveJSON changes the defCausumn capacity to causetstore n JSON elements and set the length to zero.
   431  func (c *DeferredCauset) ReserveJSON(n int) {
   432  	c.reserve(n, 8)
   433  }
   434  
   435  // ReserveSet changes the defCausumn capacity to causetstore n set elements and set the length to zero.
   436  func (c *DeferredCauset) ReserveSet(n int) {
   437  	c.reserve(n, 8)
   438  }
   439  
   440  // ReserveEnum changes the defCausumn capacity to causetstore n enum elements and set the length to zero.
   441  func (c *DeferredCauset) ReserveEnum(n int) {
   442  	c.reserve(n, 8)
   443  }
   444  
   445  func (c *DeferredCauset) castSliceHeader(header *reflect.SliceHeader, typeSize int) {
   446  	header.Data = (*reflect.SliceHeader)(unsafe.Pointer(&c.data)).Data
   447  	header.Len = c.length
   448  	header.Cap = cap(c.data) / typeSize
   449  }
   450  
   451  // Int64s returns an int64 slice stored in this DeferredCauset.
   452  func (c *DeferredCauset) Int64s() []int64 {
   453  	var res []int64
   454  	c.castSliceHeader((*reflect.SliceHeader)(unsafe.Pointer(&res)), sizeInt64)
   455  	return res
   456  }
   457  
   458  // Uint64s returns a uint64 slice stored in this DeferredCauset.
   459  func (c *DeferredCauset) Uint64s() []uint64 {
   460  	var res []uint64
   461  	c.castSliceHeader((*reflect.SliceHeader)(unsafe.Pointer(&res)), sizeUint64)
   462  	return res
   463  }
   464  
   465  // Float32s returns a float32 slice stored in this DeferredCauset.
   466  func (c *DeferredCauset) Float32s() []float32 {
   467  	var res []float32
   468  	c.castSliceHeader((*reflect.SliceHeader)(unsafe.Pointer(&res)), sizeFloat32)
   469  	return res
   470  }
   471  
   472  // Float64s returns a float64 slice stored in this DeferredCauset.
   473  func (c *DeferredCauset) Float64s() []float64 {
   474  	var res []float64
   475  	c.castSliceHeader((*reflect.SliceHeader)(unsafe.Pointer(&res)), sizeFloat64)
   476  	return res
   477  }
   478  
   479  // GoDurations returns a Golang time.Duration slice stored in this DeferredCauset.
   480  // Different from the Row.GetDuration method, the argument Fsp is ignored, so the user should handle it outside.
   481  func (c *DeferredCauset) GoDurations() []time.Duration {
   482  	var res []time.Duration
   483  	c.castSliceHeader((*reflect.SliceHeader)(unsafe.Pointer(&res)), sizeGoDuration)
   484  	return res
   485  }
   486  
   487  // Decimals returns a MyDecimal slice stored in this DeferredCauset.
   488  func (c *DeferredCauset) Decimals() []types.MyDecimal {
   489  	var res []types.MyDecimal
   490  	c.castSliceHeader((*reflect.SliceHeader)(unsafe.Pointer(&res)), sizeMyDecimal)
   491  	return res
   492  }
   493  
   494  // Times returns a Time slice stored in this DeferredCauset.
   495  func (c *DeferredCauset) Times() []types.Time {
   496  	var res []types.Time
   497  	c.castSliceHeader((*reflect.SliceHeader)(unsafe.Pointer(&res)), sizeTime)
   498  	return res
   499  }
   500  
   501  // GetInt64 returns the int64 in the specific event.
   502  func (c *DeferredCauset) GetInt64(rowID int) int64 {
   503  	return *(*int64)(unsafe.Pointer(&c.data[rowID*8]))
   504  }
   505  
   506  // GetUint64 returns the uint64 in the specific event.
   507  func (c *DeferredCauset) GetUint64(rowID int) uint64 {
   508  	return *(*uint64)(unsafe.Pointer(&c.data[rowID*8]))
   509  }
   510  
   511  // GetFloat32 returns the float32 in the specific event.
   512  func (c *DeferredCauset) GetFloat32(rowID int) float32 {
   513  	return *(*float32)(unsafe.Pointer(&c.data[rowID*4]))
   514  }
   515  
   516  // GetFloat64 returns the float64 in the specific event.
   517  func (c *DeferredCauset) GetFloat64(rowID int) float64 {
   518  	return *(*float64)(unsafe.Pointer(&c.data[rowID*8]))
   519  }
   520  
   521  // GetDecimal returns the decimal in the specific event.
   522  func (c *DeferredCauset) GetDecimal(rowID int) *types.MyDecimal {
   523  	return (*types.MyDecimal)(unsafe.Pointer(&c.data[rowID*types.MyDecimalStructSize]))
   524  }
   525  
   526  // GetString returns the string in the specific event.
   527  func (c *DeferredCauset) GetString(rowID int) string {
   528  	return string(replog.String(c.data[c.offsets[rowID]:c.offsets[rowID+1]]))
   529  }
   530  
   531  // GetJSON returns the JSON in the specific event.
   532  func (c *DeferredCauset) GetJSON(rowID int) json.BinaryJSON {
   533  	start := c.offsets[rowID]
   534  	return json.BinaryJSON{TypeCode: c.data[start], Value: c.data[start+1 : c.offsets[rowID+1]]}
   535  }
   536  
   537  // GetBytes returns the byte slice in the specific event.
   538  func (c *DeferredCauset) GetBytes(rowID int) []byte {
   539  	return c.data[c.offsets[rowID]:c.offsets[rowID+1]]
   540  }
   541  
   542  // GetEnum returns the Enum in the specific event.
   543  func (c *DeferredCauset) GetEnum(rowID int) types.Enum {
   544  	name, val := c.getNameValue(rowID)
   545  	return types.Enum{Name: name, Value: val}
   546  }
   547  
   548  // GetSet returns the Set in the specific event.
   549  func (c *DeferredCauset) GetSet(rowID int) types.Set {
   550  	name, val := c.getNameValue(rowID)
   551  	return types.Set{Name: name, Value: val}
   552  }
   553  
   554  // GetTime returns the Time in the specific event.
   555  func (c *DeferredCauset) GetTime(rowID int) types.Time {
   556  	return *(*types.Time)(unsafe.Pointer(&c.data[rowID*sizeTime]))
   557  }
   558  
   559  // GetDuration returns the Duration in the specific event.
   560  func (c *DeferredCauset) GetDuration(rowID int, fillFsp int) types.Duration {
   561  	dur := *(*int64)(unsafe.Pointer(&c.data[rowID*8]))
   562  	return types.Duration{Duration: time.Duration(dur), Fsp: int8(fillFsp)}
   563  }
   564  
   565  func (c *DeferredCauset) getNameValue(rowID int) (string, uint64) {
   566  	start, end := c.offsets[rowID], c.offsets[rowID+1]
   567  	if start == end {
   568  		return "", 0
   569  	}
   570  	var val uint64
   571  	copy((*[8]byte)(unsafe.Pointer(&val))[:], c.data[start:])
   572  	return string(replog.String(c.data[start+8 : end])), val
   573  }
   574  
   575  // GetRaw returns the underlying raw bytes in the specific event.
   576  func (c *DeferredCauset) GetRaw(rowID int) []byte {
   577  	var data []byte
   578  	if c.isFixed() {
   579  		elemLen := len(c.elemBuf)
   580  		data = c.data[rowID*elemLen : rowID*elemLen+elemLen]
   581  	} else {
   582  		data = c.data[c.offsets[rowID]:c.offsets[rowID+1]]
   583  	}
   584  	return data
   585  }
   586  
   587  // SetRaw sets the raw bytes for the rowIdx-th element.
   588  // NOTE: Two conditions must be satisfied before calling this function:
   589  // 1. The defCausumn should be stored with variable-length elements.
   590  // 2. The length of the new element should be exactly the same as the old one.
   591  func (c *DeferredCauset) SetRaw(rowID int, bs []byte) {
   592  	copy(c.data[c.offsets[rowID]:c.offsets[rowID+1]], bs)
   593  }
   594  
   595  // reconstruct reconstructs this DeferredCauset by removing all filtered rows in it according to sel.
   596  func (c *DeferredCauset) reconstruct(sel []int) {
   597  	if sel == nil {
   598  		return
   599  	}
   600  	if c.isFixed() {
   601  		elemLen := len(c.elemBuf)
   602  		for dst, src := range sel {
   603  			idx := dst >> 3
   604  			pos := uint16(dst & 7)
   605  			if c.IsNull(src) {
   606  				c.nullBitmap[idx] &= ^byte(1 << pos)
   607  			} else {
   608  				copy(c.data[dst*elemLen:dst*elemLen+elemLen], c.data[src*elemLen:src*elemLen+elemLen])
   609  				c.nullBitmap[idx] |= byte(1 << pos)
   610  			}
   611  		}
   612  		c.data = c.data[:len(sel)*elemLen]
   613  	} else {
   614  		tail := 0
   615  		for dst, src := range sel {
   616  			idx := dst >> 3
   617  			pos := uint(dst & 7)
   618  			if c.IsNull(src) {
   619  				c.nullBitmap[idx] &= ^byte(1 << pos)
   620  				c.offsets[dst+1] = int64(tail)
   621  			} else {
   622  				start, end := c.offsets[src], c.offsets[src+1]
   623  				copy(c.data[tail:], c.data[start:end])
   624  				tail += int(end - start)
   625  				c.offsets[dst+1] = int64(tail)
   626  				c.nullBitmap[idx] |= byte(1 << pos)
   627  			}
   628  		}
   629  		c.data = c.data[:tail]
   630  		c.offsets = c.offsets[:len(sel)+1]
   631  	}
   632  	c.length = len(sel)
   633  
   634  	// clean nullBitmap
   635  	c.nullBitmap = c.nullBitmap[:(len(sel)+7)>>3]
   636  	idx := len(sel) >> 3
   637  	if idx < len(c.nullBitmap) {
   638  		pos := uint16(len(sel) & 7)
   639  		c.nullBitmap[idx] &= byte((1 << pos) - 1)
   640  	}
   641  }
   642  
   643  // CopyReconstruct copies this DeferredCauset to dst and removes unselected rows.
   644  // If dst is nil, it creates a new DeferredCauset and returns it.
   645  func (c *DeferredCauset) CopyReconstruct(sel []int, dst *DeferredCauset) *DeferredCauset {
   646  	if sel == nil {
   647  		return c.CopyConstruct(dst)
   648  	}
   649  
   650  	selLength := len(sel)
   651  	if selLength == c.length {
   652  		// The variable 'ascend' is used to check if the sel array is in ascending order
   653  		ascend := true
   654  		for i := 1; i < selLength; i++ {
   655  			if sel[i] < sel[i-1] {
   656  				ascend = false
   657  				break
   658  			}
   659  		}
   660  		if ascend {
   661  			return c.CopyConstruct(dst)
   662  		}
   663  	}
   664  
   665  	if dst == nil {
   666  		dst = newDeferredCauset(c.typeSize(), len(sel))
   667  	} else {
   668  		dst.reset()
   669  	}
   670  
   671  	if c.isFixed() {
   672  		elemLen := len(c.elemBuf)
   673  		dst.elemBuf = make([]byte, elemLen)
   674  		for _, i := range sel {
   675  			dst.appendNullBitmap(!c.IsNull(i))
   676  			dst.data = append(dst.data, c.data[i*elemLen:i*elemLen+elemLen]...)
   677  			dst.length++
   678  		}
   679  	} else {
   680  		dst.elemBuf = nil
   681  		if len(dst.offsets) == 0 {
   682  			dst.offsets = append(dst.offsets, 0)
   683  		}
   684  		for _, i := range sel {
   685  			dst.appendNullBitmap(!c.IsNull(i))
   686  			start, end := c.offsets[i], c.offsets[i+1]
   687  			dst.data = append(dst.data, c.data[start:end]...)
   688  			dst.offsets = append(dst.offsets, int64(len(dst.data)))
   689  			dst.length++
   690  		}
   691  	}
   692  	return dst
   693  }
   694  
   695  // MergeNulls merges these defCausumns' null bitmaps.
   696  // For a event, if any defCausumn of it is null, the result is null.
   697  // It works like: if defCaus1.IsNull || defCaus2.IsNull || defCaus3.IsNull.
   698  // The caller should ensure that all these defCausumns have the same
   699  // length, and data stored in the result defCausumn is fixed-length type.
   700  func (c *DeferredCauset) MergeNulls(defcaus ...*DeferredCauset) {
   701  	if !c.isFixed() {
   702  		panic("result defCausumn should be fixed-length type")
   703  	}
   704  	for _, defCaus := range defcaus {
   705  		if c.length != defCaus.length {
   706  			panic(fmt.Sprintf("should ensure all defCausumns have the same length, expect %v, but got %v", c.length, defCaus.length))
   707  		}
   708  	}
   709  	for _, defCaus := range defcaus {
   710  		for i := range c.nullBitmap {
   711  			// bit 0 is null, 1 is not null, so do AND operations here.
   712  			c.nullBitmap[i] &= defCaus.nullBitmap[i]
   713  		}
   714  	}
   715  }