// 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 DORIS_BE_RUNTIME_DPP_SINK_INTERNAL_H #define DORIS_BE_RUNTIME_DPP_SINK_INTERNAL_H #include #include #include "common/status.h" #include "gen_cpp/Types_types.h" #include "runtime/primitive_type.h" #include "runtime/raw_value.h" #include "util/hash_util.hpp" namespace doris { class ExprContext; class MemTracker; class ObjectPool; class RuntimeState; class RowDescriptor; class TRollupSchema; class TPartitionKey; class TPartitionRange; class TRangePartition; class RollupSchema { public: RollupSchema(); ~RollupSchema(); static Status from_thrift(ObjectPool* pool, const TRollupSchema& t_schema, RollupSchema* schema); Status prepare(RuntimeState* state, const RowDescriptor& row_desc, const std::shared_ptr& mem_tracker); Status open(RuntimeState* state); void close(RuntimeState* state); const std::string& keys_type() const { return _keys_type; } const std::vector& keys() const { return _key_ctxs; } const std::vector& values() const { return _value_ctxs; } const std::vector& value_ops() const { return _value_ops; } private: std::string _keys_type; std::vector _key_ctxs; std::vector _value_ctxs; std::vector _value_ops; }; class PartRangeKey { public: PartRangeKey() {} ~PartRangeKey() {} static const PartRangeKey& pos_infinite() { return _s_pos_infinite; } static const PartRangeKey& neg_infinite() { return _s_neg_infinite; } static Status from_thrift(ObjectPool* pool, const TPartitionKey& t_key, PartRangeKey* key); static Status from_value(PrimitiveType type, void* value, PartRangeKey* key); bool operator==(const PartRangeKey& other) const { if (_sign != other._sign) { return false; } if (_sign != 0) { return true; } return RawValue::compare(_key, other._key, TypeDescriptor(_type)) == 0; } bool operator!=(const PartRangeKey& other) const { return !(*this == other); } bool operator<(const PartRangeKey& other) const { if (_sign < other._sign) { return true; } else if (_sign > other._sign) { return false; } if (_sign != 0) { return false; } return RawValue::compare(_key, other._key, TypeDescriptor(_type)) < 0; } bool operator<=(const PartRangeKey& other) const { return *this < other || *this == other; } bool operator>(const PartRangeKey& other) const { return !(*this <= other); } bool operator>=(const PartRangeKey& other) const { return !(*this < other); } std::string debug_string() const { std::stringstream debug_str; debug_str << "sign: " << _sign << "; " << "type: " << type_to_string(_type) << "; " << "key: " << _str_key; return debug_str.str(); } private: // Used for static variables PartRangeKey(int sign) : _sign(sign) {} // When sign is less than 0, that key represent negative infinite // When sign is greater than 0, that key represent positive infinite // When sign is equal 0, that key represent normal key int _sign; PrimitiveType _type; void* _key; std::string _str_key; static PartRangeKey _s_pos_infinite; static PartRangeKey _s_neg_infinite; }; class PartRange { public: PartRange() {} ~PartRange() {} static const PartRange& all() { return _s_all_range; } static Status from_thrift(ObjectPool* pool, const TPartitionRange& t_part_range, PartRange* range); // return -1 : 'this' range is on the left of 'key' // return 0 : 'this' range contains 'key' // return 1 : 'this' range is on the right of 'key' int compare_key(const PartRangeKey& key) const { if (_start_key > key) { return 1; } else if (_start_key == key) { if (!_include_start_key) { return 1; } else { return 0; } } else if (_end_key < key) { return -1; } else if (_end_key == key) { if (!_include_end_key) { return -1; } } return 0; } // NOTE: operator "<" and ">" is reciprocal for PartRange, but is not always exist. // e.g. [1, 3) is neither '<' nor '=' nor '>' [2, 4) bool operator<(const PartRange& other) const { VLOG_ROW << "in PartRange::operator<: " << std::endl << "this: " << debug_string() << std::endl << "other: " << other.debug_string() << std::endl; if (_end_key < other._start_key) { VLOG_ROW << "in PartRange::operator<: result: " << true << std::endl; return true; } else if (_end_key == other._start_key) { if ((_include_end_key && other._include_start_key) == false) { VLOG_ROW << "in PartRange::operator<: result: " << true << std::endl; return true; } VLOG_ROW << "in PartRange::operator<. " << "first.end=other.end. but include judge failed." << std::endl; } VLOG_ROW << "in PartRange::operator<: result: " << false << std::endl; return false; } std::string debug_string() const { std::stringstream debug_str; debug_str << "start_key: [" << _start_key.debug_string() << "]; " << "end_key: [" << _end_key.debug_string() << "]; " << "include_start: " << _include_start_key << "; " << "include_end: " << _include_end_key << ";"; return debug_str.str(); } private: PartRange(const PartRangeKey& start_key, const PartRangeKey& end_key, bool include_start, bool include_end) : _start_key(start_key), _end_key(end_key), _include_start_key(include_start), _include_end_key(include_end) {} PartRangeKey _start_key; PartRangeKey _end_key; bool _include_start_key; bool _include_end_key; static PartRange _s_all_range; }; class PartitionInfo { public: PartitionInfo() : _id(-1), _distributed_bucket(0) {} static Status from_thrift(ObjectPool* pool, const TRangePartition& t_partition, PartitionInfo* partition); Status prepare(RuntimeState* state, const RowDescriptor& row_desc, const std::shared_ptr& mem_tracker); Status open(RuntimeState* state); void close(RuntimeState* state); int64_t id() const { return _id; } const std::vector& distributed_expr_ctxs() const { return _distributed_expr_ctxs; } int distributed_bucket() const { return _distributed_bucket; } const PartRange& range() const { return _range; } private: int64_t _id; PartRange _range; // Information used to distribute data // distribute exprs std::vector _distributed_expr_ctxs; int32_t _distributed_bucket; }; // which tablet this batch belong to // TODO(zc): remove rollup struct TabletDesc { int64_t partition_id; uint32_t bucket_id; bool operator==(const TabletDesc& other) const { return (bucket_id == other.bucket_id) && (partition_id == other.partition_id); } }; } // namespace doris namespace std { // TODO(zc) template <> struct hash { std::size_t operator()(const doris::TabletDesc& desc) const { uint32_t seed = 0; seed = doris::HashUtil::crc_hash(&desc.partition_id, sizeof(desc.partition_id), seed); seed = doris::HashUtil::crc_hash(&desc.bucket_id, sizeof(desc.bucket_id), seed); return seed; } }; } // namespace std #endif