blob: dff39d5212feda4f3f527644b527d2e7c302efe3 [file]
// 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.
#pragma once
#include <gen_cpp/Metrics_types.h>
#include <gen_cpp/Types_types.h>
#include <glog/logging.h>
#include <atomic>
#include <functional>
#include <utility>
#include "exec/partitioner/partitioner.h"
#include "runtime/fragment_mgr.h"
#include "runtime/memory/mem_tracker_limiter.h"
#include "runtime/query_context.h"
#include "runtime/runtime_profile.h"
#include "runtime/runtime_state.h"
#include "runtime/thread_context.h"
namespace doris {
// Default spill partitioner for initial partitioning (level-0). Repartition
// paths may use different channel-id policies (e.g. raw-hash mode).
using SpillPartitionerType = Crc32HashPartitioner<SpillPartitionChannelIds>;
// Repartition partitioner: keeps raw hash (no final modulo) so SpillRepartitioner
// can apply level-aware hash mixing and channel mapping.
using SpillRePartitionerType = Crc32HashPartitioner<SpillRePartitionChannelIds>;
struct SpillContext {
std::atomic_int running_tasks_count;
TUniqueId query_id;
std::function<void(SpillContext*)> all_tasks_finished_callback;
SpillContext(int running_tasks_count_, TUniqueId query_id_,
std::function<void(SpillContext*)> all_tasks_finished_callback_)
: running_tasks_count(running_tasks_count_),
query_id(std::move(query_id_)),
all_tasks_finished_callback(std::move(all_tasks_finished_callback_)) {}
~SpillContext() {
if (running_tasks_count.load() != 0) {
LOG(WARNING) << "Query: " << print_id(query_id)
<< " not all spill tasks finished, remaining tasks: "
<< running_tasks_count.load();
}
}
void on_task_finished() {
auto count = running_tasks_count.fetch_sub(1);
if (count == 1) {
all_tasks_finished_callback(this);
}
}
};
template <bool accumulating>
inline void update_profile_from_inner_profile(const std::string& name,
RuntimeProfile* runtime_profile,
RuntimeProfile* inner_profile) {
auto* inner_counter = inner_profile->get_counter(name);
DCHECK(inner_counter != nullptr) << "inner counter " << name << " not found";
if (inner_counter == nullptr) [[unlikely]] {
return;
}
auto* counter = runtime_profile->get_counter(name);
if (counter == nullptr) [[unlikely]] {
counter = runtime_profile->add_counter(name, inner_counter->type(), "",
inner_counter->level());
}
if constexpr (accumulating) {
// Memory usage should not be accumulated.
if (counter->type() == TUnit::BYTES) {
counter->set(inner_counter->value());
} else {
counter->update(inner_counter->value());
}
} else {
counter->set(inner_counter->value());
}
}
} // namespace doris