| 102 | } |
| 103 | |
| 104 | void Tuple::DeepCopyVarlenData(const TupleDescriptor& desc, MemPool* pool) { |
| 105 | // allocate then copy all non-null string and collection slots |
| 106 | for (vector<SlotDescriptor*>::const_iterator slot = desc.string_slots().begin(); |
| 107 | slot != desc.string_slots().end(); ++slot) { |
| 108 | DCHECK((*slot)->type().IsVarLenStringType()); |
| 109 | if (IsNull((*slot)->null_indicator_offset())) continue; |
| 110 | StringValue* string_v = GetStringSlot((*slot)->tuple_offset()); |
| 111 | // It is safe to smallify at this point as DeepCopyVarlenData is called on the new |
| 112 | // tuple which can be modified. |
| 113 | if (string_v->Smallify()) continue; |
| 114 | char* string_copy = reinterpret_cast<char*>(pool->Allocate(string_v->Len())); |
| 115 | Ubsan::MemCpy(string_copy, string_v->Ptr(), string_v->Len()); |
| 116 | string_v->SetPtr(string_copy); |
| 117 | } |
| 118 | |
| 119 | for (vector<SlotDescriptor*>::const_iterator slot = desc.collection_slots().begin(); |
| 120 | slot != desc.collection_slots().end(); ++slot) { |
| 121 | DCHECK((*slot)->type().IsCollectionType()); |
| 122 | if (IsNull((*slot)->null_indicator_offset())) continue; |
| 123 | CollectionValue* cv = GetCollectionSlot((*slot)->tuple_offset()); |
| 124 | const TupleDescriptor* item_desc = (*slot)->children_tuple_descriptor(); |
| 125 | int coll_byte_size = cv->num_tuples * item_desc->byte_size(); |
| 126 | uint8_t* coll_data = reinterpret_cast<uint8_t*>(pool->Allocate(coll_byte_size)); |
| 127 | memcpy(coll_data, cv->ptr, coll_byte_size); |
| 128 | cv->ptr = coll_data; |
| 129 | if (!item_desc->HasVarlenSlots()) continue; |
| 130 | |
| 131 | for (int i = 0; i < cv->num_tuples; ++i) { |
| 132 | int item_offset = i * item_desc->byte_size(); |
| 133 | Tuple* dst_item = reinterpret_cast<Tuple*>(coll_data + item_offset); |
| 134 | dst_item->DeepCopyVarlenData(*item_desc, pool); |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | void Tuple::DeepCopy(const TupleDescriptor& desc, char** data, int* offset, |
| 140 | bool convert_ptrs) const { |
no test coverage detected