Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
tuple-row-compare.h
Go to the documentation of this file.
1 // Copyright 2012 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 
15 
16 #ifndef IMPALA_UTIL_TUPLE_ROW_COMPARE_H_
17 #define IMPALA_UTIL_TUPLE_ROW_COMPARE_H_
18 
19 #include "exprs/expr.h"
20 #include "exprs/expr-context.h"
21 #include "runtime/tuple.h"
22 #include "runtime/tuple-row.h"
23 #include "runtime/descriptors.h"
24 
25 namespace impala {
26 
28  public:
35  const std::vector<ExprContext*>& key_expr_ctxs_lhs,
36  const std::vector<ExprContext*>& key_expr_ctxs_rhs,
37  const std::vector<bool>& is_asc,
38  const std::vector<bool>& nulls_first)
39  : key_expr_ctxs_lhs_(key_expr_ctxs_lhs),
40  key_expr_ctxs_rhs_(key_expr_ctxs_rhs),
41  is_asc_(is_asc) {
42  DCHECK_EQ(key_expr_ctxs_lhs.size(), key_expr_ctxs_rhs.size());
43  DCHECK_EQ(key_expr_ctxs_lhs.size(), is_asc.size());
44  DCHECK_EQ(key_expr_ctxs_lhs.size(), nulls_first.size());
45  nulls_first_.reserve(key_expr_ctxs_lhs.size());
46  for (int i = 0; i < key_expr_ctxs_lhs.size(); ++i) {
47  nulls_first_.push_back(nulls_first[i] ? -1 : 1);
48  }
49  }
50 
52  const std::vector<ExprContext*>& key_expr_ctxs_lhs,
53  const std::vector<ExprContext*>& key_expr_ctxs_rhs,
54  bool is_asc, bool nulls_first)
55  : key_expr_ctxs_lhs_(key_expr_ctxs_lhs),
56  key_expr_ctxs_rhs_(key_expr_ctxs_rhs),
57  is_asc_(key_expr_ctxs_lhs.size(), is_asc),
58  nulls_first_(key_expr_ctxs_lhs.size(), nulls_first ? -1 : 1) {
59  DCHECK_EQ(key_expr_ctxs_lhs.size(), key_expr_ctxs_rhs.size());
60  }
61 
65  int Compare(TupleRow* lhs, TupleRow* rhs) const {
66  for (int i = 0; i < key_expr_ctxs_lhs_.size(); ++i) {
67  void* lhs_value = key_expr_ctxs_lhs_[i]->GetValue(lhs);
68  void* rhs_value = key_expr_ctxs_rhs_[i]->GetValue(rhs);
69 
70  // The sort order of NULLs is independent of asc/desc.
71  if (lhs_value == NULL && rhs_value == NULL) continue;
72  if (lhs_value == NULL && rhs_value != NULL) return nulls_first_[i];
73  if (lhs_value != NULL && rhs_value == NULL) return -nulls_first_[i];
74 
75  int result = RawValue::Compare(lhs_value, rhs_value,
76  key_expr_ctxs_lhs_[i]->root()->type());
77  if (!is_asc_[i]) result = -result;
78  if (result != 0) return result;
79  // Otherwise, try the next Expr
80  }
81  return 0; // fully equivalent key
82  }
83 
87  bool operator() (TupleRow* lhs, TupleRow* rhs) const {
88  int result = Compare(lhs, rhs);
89  if (result < 0) return true;
90  return false;
91  }
92 
93  bool operator() (Tuple* lhs, Tuple* rhs) const {
94  TupleRow* lhs_row = reinterpret_cast<TupleRow*>(&lhs);
95  TupleRow* rhs_row = reinterpret_cast<TupleRow*>(&rhs);
96  return (*this)(lhs_row, rhs_row);
97  }
98 
99  private:
100  std::vector<ExprContext*> key_expr_ctxs_lhs_;
101  std::vector<ExprContext*> key_expr_ctxs_rhs_;
102  std::vector<bool> is_asc_;
103  std::vector<int8_t> nulls_first_;
104 };
105 
109 
110  TupleEqualityChecker(TupleDescriptor* tuple_desc) : tuple_desc_(tuple_desc) {
111  }
112 
113  bool operator() (Tuple* x, Tuple* y) {
114  const std::vector<SlotDescriptor*>& slots = tuple_desc_->slots();
115  for (int i = 0; i < slots.size(); ++i) {
116  SlotDescriptor* slot = slots[i];
117 
118  if (slot->is_nullable()) {
119  const NullIndicatorOffset& null_offset = slot->null_indicator_offset();
120  if (x->IsNull(null_offset) || y->IsNull(null_offset)) {
121  if (x->IsNull(null_offset) && y->IsNull(null_offset)) {
122  continue;
123  } else {
124  return false;
125  }
126  }
127  }
128 
129  int tuple_offset = slot->tuple_offset();
130  const ColumnType& type = slot->type();
131  if (!RawValue::Eq(x->GetSlot(tuple_offset), y->GetSlot(tuple_offset), type)) {
132  return false;
133  }
134  }
135 
136  return true;
137  }
138 };
139 
142  std::vector<TupleEqualityChecker> tuple_checkers_;
143 
145  const std::vector<TupleDescriptor*>& tuple_descs = row_desc.tuple_descriptors();
146  for (int i = 0; i < tuple_descs.size(); ++i) {
147  tuple_checkers_.push_back(TupleEqualityChecker(tuple_descs[i]));
148  }
149  }
150 
152  for (int i = 0; i < tuple_checkers_.size(); ++i) {
153  Tuple* x_tuple = x->GetTuple(i);
154  Tuple* y_tuple = y->GetTuple(i);
155  if (!tuple_checkers_[i](x_tuple, y_tuple)) return false;
156  }
157 
158  return true;
159  }
160 };
161 
162 }
163 
164 #endif
bool operator()(TupleRow *x, TupleRow *y)
Tuple * GetTuple(int tuple_idx)
Definition: tuple-row.h:30
static bool Eq(const void *v1, const void *v2, const ColumnType &type)
Definition: raw-value.h:106
Compares the equality of two Tuples, going slot by slot.
A tuple with 0 materialised slots is represented as NULL.
Definition: tuple.h:48
TupleEqualityChecker(TupleDescriptor *tuple_desc)
Compares the equality of two TupleRows, going tuple by tuple.
void * GetSlot(int offset)
Definition: tuple.h:118
const std::vector< SlotDescriptor * > & slots() const
Definition: descriptors.h:302
const NullIndicatorOffset & null_indicator_offset() const
Definition: descriptors.h:89
std::vector< TupleEqualityChecker > tuple_checkers_
bool IsNull(const NullIndicatorOffset &offset) const
Definition: tuple.h:112
bool is_nullable() const
Definition: descriptors.h:93
TupleRowComparator(const std::vector< ExprContext * > &key_expr_ctxs_lhs, const std::vector< ExprContext * > &key_expr_ctxs_rhs, bool is_asc, bool nulls_first)
const ColumnType & type() const
Definition: descriptors.h:78
TupleRowComparator(const std::vector< ExprContext * > &key_expr_ctxs_lhs, const std::vector< ExprContext * > &key_expr_ctxs_rhs, const std::vector< bool > &is_asc, const std::vector< bool > &nulls_first)
bool operator()(TupleRow *lhs, TupleRow *rhs) const
const RowDescriptor & row_desc() const
const std::vector< TupleDescriptor * > & tuple_descriptors() const
Return descriptors for all tuples in this row, in order of appearance.
Definition: descriptors.h:412
std::vector< bool > is_asc_
std::vector< ExprContext * > key_expr_ctxs_rhs_
bool operator()(Tuple *x, Tuple *y)
static int Compare(const void *v1, const void *v2, const ColumnType &type)
Definition: raw-value.cc:109
std::vector< ExprContext * > key_expr_ctxs_lhs_
std::vector< int8_t > nulls_first_
int tuple_offset() const
Definition: descriptors.h:88
RowEqualityChecker(const RowDescriptor &row_desc)
int Compare(TupleRow *lhs, TupleRow *rhs) const