blob: 852bd9d35035ff6cf246cd8f3129e4f07285da38 [file]
// Copyright 2022 The Blaze Authors
//
// Licensed 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 <arrow/result.h>
#include <arrow/type.h>
#include <cudf/table/table.hpp>
#include <cudf/table/table_view.hpp>
#include <memory>
#include <optional>
#include <ostream>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <vector>
class OwnedTable {
public:
inline OwnedTable(std::unique_ptr<cudf::table> owned) :
owned(std::make_optional(std::move(owned))) {
}
inline OwnedTable(std::shared_ptr<OwnedTable> holder, cudf::table_view referenced) :
referenced(std::make_pair(holder, referenced)) {
}
inline OwnedTable(OwnedTable&& moving) :
owned(std::move(moving.owned)), referenced(std::move(moving.referenced)) {
}
inline cudf::table_view view() const {
if (owned.has_value()) {
return owned.value()->view();
}
return referenced.value().second;
}
private:
std::optional<std::unique_ptr<cudf::table>> owned;
std::optional<std::pair<std::shared_ptr<OwnedTable>, cudf::table_view>> referenced;
};
class TableStream {
public:
TableStream() {
}
virtual ~TableStream() {
}
public:
virtual arrow::Result<bool> has_next() = 0;
virtual arrow::Result<OwnedTable> next() = 0;
inline static std::unique_ptr<TableStream> empty_stream() {
class EmptyTableStream : public TableStream {
public:
inline arrow::Result<bool> has_next() {
return arrow::Result(false);
}
inline arrow::Result<OwnedTable> next() {
throw std::runtime_error("unreachable: EmptyTableStream has no tables");
}
};
return std::make_unique<EmptyTableStream>();
}
};
class Plan {
public:
Plan() {
}
virtual ~Plan() {
}
public:
virtual void desc(std::ostream& oss) const = 0;
virtual std::shared_ptr<arrow::Schema> schema() const = 0;
virtual arrow::Result<std::unique_ptr<TableStream>> execute() const = 0;
virtual std::vector<std::shared_ptr<Plan>> children() const {
return std::vector<std::shared_ptr<Plan>>{};
}
};
inline static std::string desc_plan_tree(std::shared_ptr<Plan> plan) {
struct plan_tree_node {
std::shared_ptr<Plan> plan;
int level;
plan_tree_node(std::shared_ptr<Plan> plan, int level) : plan(plan), level(level) {
}
};
auto dfs_stack = std::stack<plan_tree_node>();
auto nodes = std::vector<plan_tree_node>{};
dfs_stack.push(plan_tree_node(plan, 0));
while (!dfs_stack.empty()) {
auto node = dfs_stack.top();
nodes.push_back(node);
dfs_stack.pop();
for (auto child : node.plan->children()) {
dfs_stack.push(plan_tree_node(child, node.level + 1));
}
}
std::ostringstream oss;
for (auto node : nodes) {
for (auto indent = 0; indent < 2 * node.level; indent++) {
oss << " ";
}
node.plan->desc(oss);
oss << std::endl;
}
return oss.str();
}