| 373 | } |
| 374 | |
| 375 | static void scanArrowArrayRunEndEncoded(const ArrowSchema* schema, const ArrowArray* array, |
| 376 | ValueVector& outputVector, ArrowNullMaskTree* mask, uint64_t srcOffset, uint64_t dstOffset, |
| 377 | uint64_t count) { |
| 378 | |
| 379 | const ArrowArray* runEndArray = array->children[0]; |
| 380 | auto runEndBuffer = (const uint32_t*)runEndArray->buffers[1]; |
| 381 | |
| 382 | // binary search run end corresponding to srcOffset |
| 383 | auto runEndIdx = runEndArray->offset; |
| 384 | { |
| 385 | auto L = runEndArray->offset, H = L + runEndArray->length; |
| 386 | while (H >= L) { |
| 387 | auto M = (H + L) >> 1; |
| 388 | if (runEndBuffer[M] < srcOffset) { |
| 389 | runEndIdx = M; |
| 390 | H = M - 1; |
| 391 | } else { |
| 392 | L = M + 1; |
| 393 | } |
| 394 | } |
| 395 | } |
| 396 | |
| 397 | rowIter(outputVector, count, [&](auto i) { |
| 398 | while (i + srcOffset >= runEndBuffer[runEndIdx + 1]) { |
| 399 | runEndIdx++; |
| 400 | } |
| 401 | auto valuesOffseted = mask->getChild(1)->offsetBy(runEndIdx); |
| 402 | ArrowConverter::fromArrowArray(schema->children[1], array->children[1], outputVector, |
| 403 | &valuesOffseted, runEndIdx, i + dstOffset, |
| 404 | 1); // there is optimization to be made here... |
| 405 | }); |
| 406 | } |
| 407 | |
| 408 | void ArrowConverter::fromArrowArray(const ArrowSchema* schema, const ArrowArray* array, |
| 409 | ValueVector& outputVector, ArrowNullMaskTree* mask, uint64_t srcOffset, uint64_t dstOffset, |
no test coverage detected