blob: e0f459d1c6f7474bc7d20224a5642197623fb90f [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#ifndef IMPALA_EXEC_EXCHANGE_NODE_H
#define IMPALA_EXEC_EXCHANGE_NODE_H
#include <boost/scoped_ptr.hpp>
#include "exec/exec-node.h"
#include "runtime/bufferpool/buffer-pool.h"
namespace impala {
class KrpcDataStreamRecvr;
class RowBatch;
class ScalarExpr;
class TupleRowComparator;
class ExchangePlanNode : public PlanNode {
public:
virtual Status Init(const TPlanNode& tnode, RuntimeState* state) override;
virtual Status CreateExecNode(RuntimeState* state, ExecNode** node) const override;
~ExchangePlanNode(){}
/// Sort expressions and parameters passed to the merging receiver.
std::vector<ScalarExpr*> ordering_exprs_;
std::vector<bool> is_asc_order_;
std::vector<bool> nulls_first_;
};
/// Receiver node for data streams. The data stream receiver is created in Prepare()
/// and closed in Close().
/// is_merging is set to indicate that rows from different senders must be merged
/// according to the sort parameters in sort_exec_exprs_. (It is assumed that the rows
/// received from the senders themselves are sorted.)
/// If is_merging_ is true, the exchange node creates a DataStreamRecvrBase with the
/// is_merging_ flag and retrieves retrieves rows from the receiver via calls to
/// DataStreamRecvrBase::GetNext(). It also prepares, opens and closes the ordering exprs
/// in its SortExecExprs member that are used to compare rows.
/// If is_merging_ is false, the exchange node directly retrieves batches from the row
/// batch queue of the DataStreamRecvrBase via calls to DataStreamRecvrBase::GetBatch().
class ExchangeNode : public ExecNode {
public:
ExchangeNode(
ObjectPool* pool, const ExchangePlanNode& pnode, const DescriptorTbl& descs);
virtual Status Prepare(RuntimeState* state);
virtual void Codegen(RuntimeState* state);
/// Blocks until the first batch is available for consumption via GetNext().
virtual Status Open(RuntimeState* state);
virtual Status GetNext(RuntimeState* state, RowBatch* row_batch, bool* eos);
virtual Status Reset(RuntimeState* state, RowBatch* row_batch);
virtual void Close(RuntimeState* state);
/// the number of senders needs to be set after the c'tor, because it's not
/// recorded in TPlanNode, and before calling Prepare()
void set_num_senders(int num_senders) { num_senders_ = num_senders; }
protected:
virtual void DebugString(int indentation_level, std::stringstream* out) const;
private:
/// Implements GetNext() for the case where is_merging_ is true. Delegates the GetNext()
/// call to the underlying DataStreamRecvrBase.
Status GetNextMerging(RuntimeState* state, RowBatch* output_batch, bool* eos);
/// Resets input_batch_ to the next batch from the from stream_recvr_'s queue.
/// Only used when is_merging_ is false.
Status FillInputRowBatch(RuntimeState* state);
/// Releases resources of the receiver by transferring the resource ownership of
/// the most recently dequeued row batch to 'output_batch'. Also cancels the underlying
/// receiver so all senders will get unblocked. This function is called after the
/// exchange node hits end-of-stream due to reaching the node's row count limit.
/// Please note that no more rows will be returned from the receiver once this function
/// is called.
void ReleaseRecvrResources(RowBatch* output_batch);
int num_senders_; // needed for stream_recvr_ construction
/// The underlying DataStreamRecvrBase instance. Ownership is shared between this
/// exchange node instance and the DataStreamMgr used to create the receiver.
/// stream_recvr_->Close() must be called before this instance is destroyed.
std::shared_ptr<KrpcDataStreamRecvr> stream_recvr_;
/// our input rows are a prefix of the rows we produce
RowDescriptor input_row_desc_;
/// Current batch of rows from the receiver queue being processed by this node.
/// Only valid if is_merging_ is false. (If is_merging_ is true, GetNext() is
/// delegated to the receiver). Owned by the stream receiver.
RowBatch* input_batch_;
/// Next row to copy from input_batch_. For non-merging exchanges, input_batch_
/// is retrieved directly from the sender queue in the stream recvr, and rows from
/// input_batch_ must be copied to the output batch in GetNext().
int next_row_idx_;
/// The buffer pool client for allocating buffers for tuple pointers and
/// tuple data in row batches.
BufferPool::ClientHandle recvr_buffer_pool_client_;
/// time spent reconstructing received rows
RuntimeProfile::Counter* convert_row_batch_timer_;
/// True if this is a merging exchange node. If true, GetNext() is delegated to the
/// underlying stream_recvr_, and input_batch_ is not used/valid.
bool is_merging_;
/// The TupleRowComparator based on 'sort_exec_exprs_' for merging exchange.
boost::scoped_ptr<TupleRowComparator> less_than_;
/// Sort expressions and parameters passed to the merging receiver..
std::vector<ScalarExpr*> ordering_exprs_;
std::vector<bool> is_asc_order_;
std::vector<bool> nulls_first_;
/// Offset specifying number of rows to skip.
int64_t offset_;
/// Number of rows skipped so far.
int64_t num_rows_skipped_;
};
};
#endif