| 594 | } |
| 595 | |
| 596 | int32_t RowContainer::extractVariableSizeAt( |
| 597 | const char* row, |
| 598 | column_index_t column, |
| 599 | char* output) { |
| 600 | const auto rowColumn = rowColumns_[column]; |
| 601 | |
| 602 | // 4 bytes for size + N bytes for data. |
| 603 | if (isNullAt(row, rowColumn)) { |
| 604 | memset(output, 0, 4); |
| 605 | return 4; |
| 606 | } |
| 607 | |
| 608 | const auto typeKind = typeKinds_[column]; |
| 609 | if (typeKind == TypeKind::VARCHAR || typeKind == TypeKind::VARBINARY) { |
| 610 | const auto value = valueAt<StringView>(row, rowColumn.offset()); |
| 611 | const auto size = value.size(); |
| 612 | memcpy(output, &size, 4); |
| 613 | |
| 614 | if (value.isInline() || |
| 615 | reinterpret_cast<const HashStringAllocator::Header*>(value.data())[-1] |
| 616 | .size() >= value.size()) { |
| 617 | memcpy(output + 4, value.data(), size); |
| 618 | } else { |
| 619 | auto stream = HashStringAllocator::prepareRead( |
| 620 | HashStringAllocator::headerOf(value.data())); |
| 621 | stream->readBytes(output + 4, size); |
| 622 | } |
| 623 | return 4 + size; |
| 624 | } |
| 625 | |
| 626 | const auto value = valueAt<std::string_view>(row, rowColumn.offset()); |
| 627 | const auto size = value.size(); |
| 628 | |
| 629 | auto stream = prepareRead(row, rowColumn.offset()); |
| 630 | |
| 631 | memcpy(output, &size, 4); |
| 632 | stream->readBytes(output + 4, size); |
| 633 | |
| 634 | return 4 + size; |
| 635 | } |
| 636 | |
| 637 | int32_t RowContainer::storeVariableSizeAt( |
| 638 | const char* data, |