MCPcopy Create free account
hub / github.com/apache/impala / InsertTupleWithTieHandling

Method InsertTupleWithTieHandling

be/src/exec/topn-node-ir.cc:75–125  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

73}
74
75int TopNNode::Heap::InsertTupleWithTieHandling(
76 const TupleRowComparator& cmp, TopNNode* node, Tuple* materialized_tuple) {
77 DCHECK(include_ties());
78 DCHECK_EQ(capacity_, priority_queue_.Size())
79 << "Ties only need special handling when heap is at capacity";
80 const TupleDescriptor& tuple_desc = *node->output_tuple_desc_;
81 Tuple* top_tuple = priority_queue_.Top();
82 // If we need to retain ties with the current head, the logic is more complex - we
83 // have a logical heap in indices [0, heap_capacity()) of 'priority_queue_' plus
84 // some number of tuples in 'overflowed_ties_' that are equal to priority_queue_.Top()
85 // according to 'cmp'.
86 int cmp_result = cmp.Compare(materialized_tuple, top_tuple);
87 if (cmp_result == 0) {
88 // This is a duplicate of the current min, we need to include it as a tie with min.
89 Tuple* insert_tuple =
90 reinterpret_cast<Tuple*>(node->tuple_pool_->Allocate(node->tuple_byte_size()));
91 materialized_tuple->DeepCopy(insert_tuple, tuple_desc, node->tuple_pool_.get());
92 overflowed_ties_.push_back(insert_tuple);
93 return 0;
94 } else if (cmp_result > 0) {
95 // Tuple does not belong in the heap.
96 return 1;
97 } else {
98 // 'materialized_tuple' needs to be added. Figure out which other tuples, if any,
99 // need to be removed from the heap.
100 DCHECK_LT(cmp_result, 0);
101 // Pop off the head.
102 priority_queue_.Pop();
103
104 // Check if 'top_tuple' (the tuple we just popped off) is tied with the new head.
105 if (heap_capacity() > 1 && cmp.Compare(top_tuple, priority_queue_.Top()) == 0) {
106 // The new top is still tied with the tuples in 'overflowed_ties_' so we must keep
107 // it. The previous top becomes another overflowed tuple.
108 overflowed_ties_.push_back(top_tuple);
109 Tuple* insert_tuple =
110 reinterpret_cast<Tuple*>(node->tuple_pool_->Allocate(node->tuple_byte_size()));
111 materialized_tuple->DeepCopy(insert_tuple, tuple_desc, node->tuple_pool_.get());
112 // Push the new tuple onto the heap, but retain the tied tuple.
113 priority_queue_.Push(insert_tuple);
114 return 0;
115 } else {
116 // No tuples tied with 'top_tuple' are left.
117 // Reuse the fixed-length memory of 'top_tuple' to reduce allocations.
118 int64_t num_rows_replaced = overflowed_ties_.size() + 1;
119 overflowed_ties_.clear();
120 materialized_tuple->DeepCopy(top_tuple, tuple_desc, node->tuple_pool_.get());
121 priority_queue_.Push(top_tuple);
122 return num_rows_replaced;
123 }
124 }
125}
126
127void TopNNode::InsertBatchPartitioned(RuntimeState* state, RowBatch* batch) {
128 DCHECK(is_partitioned());

Callers

nothing calls this directly

Calls 12

TopMethod · 0.80
push_backMethod · 0.80
getMethod · 0.65
clearMethod · 0.65
SizeMethod · 0.45
CompareMethod · 0.45
AllocateMethod · 0.45
tuple_byte_sizeMethod · 0.45
DeepCopyMethod · 0.45
PopMethod · 0.45
PushMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected