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 }