| 64 | |
| 65 | template <bool HAS_NULLABLE_TUPLE> |
| 66 | inline void BufferedTupleStream::UnflattenTupleRow(uint8_t** data, TupleRow* row) const { |
| 67 | const int tuples_per_row = desc_->tuple_descriptors().size(); |
| 68 | uint8_t* ptr = *data; |
| 69 | if (HAS_NULLABLE_TUPLE) { |
| 70 | // Stitch together the tuples from the page and the NULL ones. |
| 71 | const uint8_t* null_indicators = ptr; |
| 72 | ptr += NullIndicatorBytesPerRow(); |
| 73 | for (int i = 0; i < tuples_per_row; ++i) { |
| 74 | const uint8_t* null_word = null_indicators + (i >> 3); |
| 75 | const uint32_t null_pos = i & 7; |
| 76 | const bool is_not_null = ((*null_word & (1 << (7 - null_pos))) == 0); |
| 77 | row->SetTuple( |
| 78 | i, reinterpret_cast<Tuple*>(reinterpret_cast<uint64_t>(ptr) * is_not_null)); |
| 79 | ptr += fixed_tuple_sizes_[i] * is_not_null; |
| 80 | } |
| 81 | } else { |
| 82 | for (int i = 0; i < tuples_per_row; ++i) { |
| 83 | row->SetTuple(i, reinterpret_cast<Tuple*>(ptr)); |
| 84 | ptr += fixed_tuple_sizes_[i]; |
| 85 | } |
| 86 | } |
| 87 | *data = ptr; |
| 88 | } |
| 89 | |
| 90 | } |
| 91 | |