| 721 | } |
| 722 | |
| 723 | void Sorter::Run::CopyVarLenDataConvertOffset(const vector<StringValue*>& string_values, |
| 724 | const vector<pair<CollectionValue*, int64_t>>& collection_values_and_sizes, |
| 725 | int page_index, const uint8_t* page_start, uint8_t* dest) { |
| 726 | DCHECK_GE(page_index, 0); |
| 727 | DCHECK_GE(dest - page_start, 0); |
| 728 | |
| 729 | for (StringValue* string_val : string_values) { |
| 730 | DCHECK(!string_val->IsSmall()); |
| 731 | memcpy(dest, string_val->Ptr(), string_val->Len()); |
| 732 | DCHECK_LE(dest - page_start, sorter_->page_len_); |
| 733 | DCHECK_LE(dest - page_start, numeric_limits<uint32_t>::max()); |
| 734 | uint32_t page_offset = dest - page_start; |
| 735 | uint64_t packed_offset = PackOffset(page_index, page_offset); |
| 736 | string_val->SetPtr(reinterpret_cast<char*>(packed_offset)); |
| 737 | dest += string_val->Len(); |
| 738 | } |
| 739 | |
| 740 | for (const pair<CollectionValue*, int64_t>& coll_val_and_size |
| 741 | : collection_values_and_sizes) { |
| 742 | CollectionValue* coll_value = coll_val_and_size.first; |
| 743 | int64_t byte_size = coll_val_and_size.second; |
| 744 | memcpy(dest, coll_value->ptr, byte_size); |
| 745 | DCHECK_LE(dest - page_start, sorter_->page_len_); |
| 746 | DCHECK_LE(dest - page_start, numeric_limits<uint32_t>::max()); |
| 747 | uint32_t page_offset = dest - page_start; |
| 748 | uint64_t packed_offset = PackOffset(page_index, page_offset); |
| 749 | coll_value->ptr = reinterpret_cast<uint8_t*>(packed_offset); |
| 750 | dest += byte_size; |
| 751 | } |
| 752 | } |
| 753 | |
| 754 | bool Sorter::Run::ConvertOffsetsToPtrs(Tuple* tuple, const TupleDescriptor& tuple_desc) { |
| 755 | // We need to be careful to handle the case where var_len_pages_ is empty, |