| 384 | |
| 385 | private: |
| 386 | IterationResult FillForLast(ElementRange* range, ElementRange* child_range, |
| 387 | PathWriteContext* context) { |
| 388 | // First fill int the remainder of the list. |
| 389 | RETURN_IF_ERROR(FillRepLevels(child_range->Size(), rep_level_, context)); |
| 390 | // Once we've reached this point the following preconditions should hold: |
| 391 | // 1. There are no more repeated path nodes to deal with. |
| 392 | // 2. All elements in |range| represent contiguous elements in the |
| 393 | // child array (Null values would have shortened the range to ensure |
| 394 | // all remaining list elements are present (though they may be empty lists)). |
| 395 | // 3. No element of range spans a parent list (intermediate |
| 396 | // list nodes only handle one list entry at a time). |
| 397 | // |
| 398 | // Given these preconditions it should be safe to fill runs on non-empty |
| 399 | // lists here and expand the range in the child node accordingly. |
| 400 | |
| 401 | while (!range->Empty()) { |
| 402 | ElementRange size_check = selector_.GetRange(range->start); |
| 403 | if (size_check.Empty()) { |
| 404 | // The empty range will need to be handled after we pass down the accumulated |
| 405 | // range because it affects def_level placement and we need to get the children |
| 406 | // def_levels entered first. |
| 407 | break; |
| 408 | } |
| 409 | // This is the start of a new list. We can be sure it only applies |
| 410 | // to the previous list (and doesn't jump to the start of any list |
| 411 | // further up in nesting due to the constraints mentioned at the start |
| 412 | // of the function). |
| 413 | RETURN_IF_ERROR(context->AppendRepLevel(prev_rep_level_)); |
| 414 | RETURN_IF_ERROR(context->AppendRepLevels(size_check.Size() - 1, rep_level_)); |
| 415 | DCHECK_EQ(size_check.start, child_range->end) |
| 416 | << size_check.start << " != " << child_range->end; |
| 417 | child_range->end = size_check.end; |
| 418 | ++range->start; |
| 419 | } |
| 420 | |
| 421 | // Do book-keeping to track the elements of the arrays that are actually visited |
| 422 | // beyond this point. This is necessary to identify "gaps" in values that should |
| 423 | // not be processed (written out to parquet). |
| 424 | context->RecordPostListVisit(*child_range); |
| 425 | return kNext; |
| 426 | } |
| 427 | |
| 428 | RangeSelector selector_; |
| 429 | int16_t prev_rep_level_; |
nothing calls this directly
no test coverage detected