|
15 | 15 | package record |
16 | 16 |
|
17 | 17 | import ( |
| 18 | + "fmt" |
18 | 19 | "unsafe" |
19 | 20 | ) |
20 | 21 |
|
@@ -226,3 +227,116 @@ func (cv *ColVal) Marshal(buf []byte) ([]byte, error) { |
226 | 227 | buf = AppendUint32Slice(buf, cv.Offset) |
227 | 228 | return buf, nil |
228 | 229 | } |
| 230 | + |
| 231 | +func resize(dst []ColVal, segs int) []ColVal { |
| 232 | + if cap(dst) < segs { |
| 233 | + delta := segs - cap(dst) |
| 234 | + dst = dst[:cap(dst)] |
| 235 | + dst = append(dst, make([]ColVal, delta)...) |
| 236 | + } |
| 237 | + dst = dst[:segs] |
| 238 | + return dst |
| 239 | +} |
| 240 | + |
| 241 | +func (cv *ColVal) Split(dst []ColVal, maxRows int, refType int) []ColVal { |
| 242 | + if maxRows <= 0 { |
| 243 | + panic(fmt.Sprintf("maxRows is %v, must grater than 0", maxRows)) |
| 244 | + } |
| 245 | + segs := (cv.Len + maxRows - 1) / maxRows |
| 246 | + dst = resize(dst, segs) |
| 247 | + |
| 248 | + start, offset, validCount := 0, 0, 0 |
| 249 | + for i := 0; i < segs; i++ { |
| 250 | + end := start + maxRows |
| 251 | + if end > cv.Len { |
| 252 | + end = cv.Len |
| 253 | + } |
| 254 | + offset, validCount = dst[i].sliceValAndOffset(cv, start, end, refType, offset) |
| 255 | + dst[i].sliceBitMap(cv, start, end) |
| 256 | + dst[i].Len = end - start |
| 257 | + dst[i].NilCount = dst[i].Len - validCount |
| 258 | + start = end |
| 259 | + } |
| 260 | + |
| 261 | + return dst |
| 262 | +} |
| 263 | + |
| 264 | +func (cv *ColVal) Length() int { |
| 265 | + return cv.Len |
| 266 | +} |
| 267 | + |
| 268 | +func (cv *ColVal) ValidCount(start, end int) int { |
| 269 | + validCount := 0 |
| 270 | + if cv.Length()+cv.NilCount == 0 || cv.Len == cv.NilCount { |
| 271 | + return validCount |
| 272 | + } |
| 273 | + if cv.NilCount == 0 { |
| 274 | + return end - start |
| 275 | + } |
| 276 | + |
| 277 | + end += cv.BitMapOffset |
| 278 | + start += cv.BitMapOffset |
| 279 | + for i := start; i < end; i++ { |
| 280 | + if cv.Bitmap[i>>3]&BitMask[i&0x07] != 0 { |
| 281 | + validCount++ |
| 282 | + } |
| 283 | + } |
| 284 | + return validCount |
| 285 | +} |
| 286 | + |
| 287 | +func (cv *ColVal) sliceValAndOffset(srcCol *ColVal, start, end, colType, valOffset int) (offset int, valueValidCount int) { |
| 288 | + var validCount, endOffset int |
| 289 | + if colType == FieldTypeInt { |
| 290 | + validCount = srcCol.ValidCount(start, end) |
| 291 | + endOffset = valOffset + Int64SizeBytes*validCount |
| 292 | + cv.Val = srcCol.Val[valOffset:endOffset] |
| 293 | + } else if colType == FieldTypeFloat { |
| 294 | + validCount = srcCol.ValidCount(start, end) |
| 295 | + endOffset = valOffset + Float64SizeBytes*validCount |
| 296 | + cv.Val = srcCol.Val[valOffset:endOffset] |
| 297 | + } else if colType == FieldTypeString { |
| 298 | + offsetStart := srcCol.Offset[start] |
| 299 | + if end == srcCol.Len { |
| 300 | + endOffset = len(srcCol.Val) |
| 301 | + } else { |
| 302 | + endOffset = int(srcCol.Offset[end]) |
| 303 | + } |
| 304 | + cv.Val = srcCol.Val[offsetStart:endOffset] |
| 305 | + cv.reserveValOffset(end - start) |
| 306 | + for index, pos := 0, start; pos < end; pos++ { |
| 307 | + cv.Offset[index] = srcCol.Offset[pos] - offsetStart |
| 308 | + index++ |
| 309 | + bitOffset := srcCol.BitMapOffset + pos |
| 310 | + if srcCol.Bitmap[bitOffset>>3]&BitMask[bitOffset&0x07] != 0 { |
| 311 | + validCount++ |
| 312 | + } |
| 313 | + } |
| 314 | + } else if colType == FieldTypeBoolean { |
| 315 | + validCount = srcCol.ValidCount(start, end) |
| 316 | + endOffset = valOffset + BooleanSizeBytes*validCount |
| 317 | + cv.Val = srcCol.Val[valOffset:endOffset] |
| 318 | + } else { |
| 319 | + panic("error type") |
| 320 | + } |
| 321 | + return endOffset, validCount |
| 322 | +} |
| 323 | + |
| 324 | +func (cv *ColVal) reserveValOffset(size int) { |
| 325 | + if cap(cv.Offset) < size { |
| 326 | + cv.Offset = make([]uint32, size) |
| 327 | + } |
| 328 | + cv.Offset = cv.Offset[:size] |
| 329 | +} |
| 330 | + |
| 331 | +func (cv *ColVal) sliceBitMap(srcCol *ColVal, start, end int) { |
| 332 | + s := srcCol.BitMapOffset + start |
| 333 | + offset := s % 8 |
| 334 | + s = s / 8 |
| 335 | + e := (srcCol.BitMapOffset + end) / 8 |
| 336 | + if (srcCol.BitMapOffset+end)%8 != 0 { |
| 337 | + e++ |
| 338 | + } |
| 339 | + |
| 340 | + cv.Bitmap = srcCol.Bitmap[s:e] |
| 341 | + cv.BitMapOffset = offset |
| 342 | +} |
0 commit comments