Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
buffered-tuple-stream-ir.cc
Go to the documentation of this file.
1 // Copyright 2014 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
17 #include "runtime/descriptors.h"
18 #include "runtime/tuple-row.h"
19 
20 using namespace impala;
21 
22 bool BufferedTupleStream::DeepCopy(TupleRow* row, uint8_t** dst) {
23  if (nullable_tuple_) {
24  return DeepCopyInternal<true>(row, dst);
25  } else {
26  return DeepCopyInternal<false>(row, dst);
27  }
28 }
29 
30 // TODO: this really needs codegen
31 template <bool HasNullableTuple>
33  if (UNLIKELY(write_block_ == NULL)) return false;
34  DCHECK_GE(null_indicators_write_block_, 0);
35  DCHECK(write_block_->is_pinned()) << DebugString() << std::endl
37 
38  const uint64_t tuples_per_row = desc_.tuple_descriptors().size();
40  (HasNullableTuple &&
41  (write_tuple_idx_ + tuples_per_row > null_indicators_write_block_ * 8)))) {
42  return false;
43  }
44  // Allocate the maximum possible buffer for the fixed portion of the tuple.
45  uint8_t* tuple_buf = write_block_->Allocate<uint8_t>(fixed_tuple_row_size_);
46  if (dst != NULL) *dst = tuple_buf;
47  // Total bytes allocated in write_block_ for this row. Saved so we can roll back
48  // if this row doesn't fit.
49  int bytes_allocated = fixed_tuple_row_size_;
50 
51  // Copy the not NULL fixed len tuples. For the NULL tuples just update the NULL tuple
52  // indicator.
53  if (HasNullableTuple) {
54  DCHECK_GT(null_indicators_write_block_, 0);
55  uint8_t* null_word = NULL;
56  uint32_t null_pos = 0;
57  // Calculate how much space it should return.
58  int to_return = 0;
59  for (int i = 0; i < tuples_per_row; ++i) {
60  null_word = write_block_->buffer() + (write_tuple_idx_ >> 3); // / 8
61  null_pos = write_tuple_idx_ & 7;
63  const int tuple_size = desc_.tuple_descriptors()[i]->byte_size();
64  Tuple* t = row->GetTuple(i);
65  const uint8_t mask = 1 << (7 - null_pos);
66  if (t != NULL) {
67  *null_word &= ~mask;
68  memcpy(tuple_buf, t, tuple_size);
69  tuple_buf += tuple_size;
70  } else {
71  *null_word |= mask;
72  to_return += tuple_size;
73  }
74  }
76  write_block_->ReturnAllocation(to_return);
77  bytes_allocated -= to_return;
78  } else {
79  // If we know that there are no nullable tuples no need to set the nullability flags.
80  DCHECK_EQ(null_indicators_write_block_, 0);
81  for (int i = 0; i < tuples_per_row; ++i) {
82  const int tuple_size = desc_.tuple_descriptors()[i]->byte_size();
83  Tuple* t = row->GetTuple(i);
84  // TODO: Once IMPALA-1306 (Avoid passing empty tuples of non-materialized slots)
85  // is delivered, the check below should become DCHECK_NOTNULL(t).
86  DCHECK(t != NULL || tuple_size == 0);
87  memcpy(tuple_buf, t, tuple_size);
88  tuple_buf += tuple_size;
89  }
90  }
91 
92  // Copy string slots. Note: we do not need to convert the string ptrs to offsets
93  // on the write path, only on the read. The tuple data is immediately followed
94  // by the string data so only the len information is necessary.
95  for (int i = 0; i < string_slots_.size(); ++i) {
96  Tuple* tuple = row->GetTuple(string_slots_[i].first);
97  if (HasNullableTuple && tuple == NULL) continue;
98  for (int j = 0; j < string_slots_[i].second.size(); ++j) {
99  const SlotDescriptor* slot_desc = string_slots_[i].second[j];
100  if (tuple->IsNull(slot_desc->null_indicator_offset())) continue;
101  StringValue* sv = tuple->GetStringSlot(slot_desc->tuple_offset());
102  if (LIKELY(sv->len > 0)) {
103  if (UNLIKELY(write_block_->BytesRemaining() < sv->len)) {
104  write_block_->ReturnAllocation(bytes_allocated);
105  return false;
106  }
107  uint8_t* buf = write_block_->Allocate<uint8_t>(sv->len);
108  bytes_allocated += sv->len;
109  memcpy(buf, sv->ptr, sv->len);
110  }
111  }
112  }
113  write_block_->AddRow();
114  ++num_rows_;
115  return true;
116 }
Tuple * GetTuple(int tuple_idx)
Definition: tuple-row.h:30
A tuple with 0 materialised slots is represented as NULL.
Definition: tuple.h:48
T * Allocate(int size)
Allocates the specified number of bytes from this block.
bool DeepCopy(TupleRow *row, uint8_t **dst)
Wrapper of the templated DeepCopyInternal() function.
int fixed_tuple_row_size_
Sum of the fixed length portion of all the tuples in desc_.
std::vector< std::pair< int, std::vector< SlotDescriptor * > > > string_slots_
Vector of all the strings slots grouped by tuple_idx.
const RowDescriptor & desc_
Description of rows stored in the stream.
const NullIndicatorOffset & null_indicator_offset() const
Definition: descriptors.h:89
bool IsNull(const NullIndicatorOffset &offset) const
Definition: tuple.h:112
int BytesRemaining() const
Return the number of remaining bytes that can be allocated in this block.
bool DeepCopyInternal(TupleRow *row, uint8_t **dst)
uint32_t write_tuple_idx_
Current idx of the tuple written at the write_block_ buffer.
std::string DebugString() const
Debug helper method to print the state of a block.
const bool nullable_tuple_
Whether any tuple in the rows is nullable.
BufferedBlockMgr::Block * write_block_
The current block for writing. NULL if there is no available block to write to.
const std::vector< TupleDescriptor * > & tuple_descriptors() const
Return descriptors for all tuples in this row, in order of appearance.
Definition: descriptors.h:412
#define UNLIKELY(expr)
Definition: compiler-util.h:33
StringValue * GetStringSlot(int offset)
Definition: tuple.h:128
#define LIKELY(expr)
Definition: compiler-util.h:32
int tuple_offset() const
Definition: descriptors.h:88
int64_t num_rows_
Number of rows stored in the stream.
void ReturnAllocation(int size)
Return size bytes from the most recent allocation.