diff --git a/flex/bin/adhoc_runner.cc b/flex/bin/adhoc_runner.cc index 976dac8b51f4..b179a7b852da 100644 --- a/flex/bin/adhoc_runner.cc +++ b/flex/bin/adhoc_runner.cc @@ -76,13 +76,15 @@ void load_params(const std::string& filename, } gs::runtime::Context eval_plan( - const physical::PhysicalPlan& plan, gs::ReadTransaction& txn, + const physical::PhysicalPlan& plan, + gs::runtime::GraphInterface& graph_interface, const std::map& params) { gs::runtime::Context ctx; + { ctx = bl::try_handle_all( - [&plan, &txn, ¶ms]() { - return gs::runtime::runtime_eval(plan, txn, params); + [&plan, &graph_interface, ¶ms]() { + return gs::runtime::runtime_eval(plan, graph_interface, params); }, [&ctx](const gs::Status& err) { LOG(FATAL) << "Error in execution: " << err.error_message(); @@ -170,6 +172,7 @@ int main(int argc, char** argv) { std::string req_file = vm["query-file"].as(); std::string query = read_pb(req_file); auto txn = db.GetReadTransaction(); + gs::runtime::GraphInterface graph_interface(txn); std::vector> map; load_params(vm["params_file"].as(), map); size_t params_num = map.size(); @@ -185,29 +188,29 @@ int main(int argc, char** argv) { double t1 = -grape::GetCurrentTime(); for (int i = 0; i < query_num; ++i) { auto& m = map[i % params_num]; - auto ctx = eval_plan(pb, txn, m); + auto ctx = eval_plan(pb, graph_interface, m); gs::Encoder output(outputs[i]); - gs::runtime::eval_sink(ctx, txn, output); + gs::runtime::eval_sink(ctx, graph_interface, output); } t1 += grape::GetCurrentTime(); double t2 = -grape::GetCurrentTime(); for (int i = 0; i < query_num; ++i) { auto& m = map[i % params_num]; - auto ctx = eval_plan(pb, txn, m); + auto ctx = eval_plan(pb, graph_interface, m); outputs[i].clear(); gs::Encoder output(outputs[i]); - gs::runtime::eval_sink(ctx, txn, output); + gs::runtime::eval_sink(ctx, graph_interface, output); } t2 += grape::GetCurrentTime(); double t3 = -grape::GetCurrentTime(); for (int i = 0; i < query_num; ++i) { auto& m = map[i % params_num]; - auto ctx = eval_plan(pb, txn, m); + auto ctx = eval_plan(pb, graph_interface, m); outputs[i].clear(); gs::Encoder output(outputs[i]); - gs::runtime::eval_sink(ctx, txn, output); + gs::runtime::eval_sink(ctx, graph_interface, output); } t3 += grape::GetCurrentTime(); diff --git a/flex/engines/graph_db/CMakeLists.txt b/flex/engines/graph_db/CMakeLists.txt index 2e91eda1394e..43ef30e9116c 100644 --- a/flex/engines/graph_db/CMakeLists.txt +++ b/flex/engines/graph_db/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(runtime) file(GLOB_RECURSE GRAPH_DB_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/app/*.cc" "${CMAKE_CURRENT_SOURCE_DIR}/database/*.cc" "${CMAKE_CURRENT_SOURCE_DIR}/app/builtin/*.cc") @@ -7,7 +6,7 @@ add_library(flex_graph_db SHARED ${GRAPH_DB_SRC_FILES}) target_include_directories(flex_graph_db PUBLIC $) target_link_libraries(flex_graph_db flex_rt_mutable_graph flex_utils ${LIBGRAPELITE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -target_link_libraries(flex_graph_db flex_plan_proto runtime_adhoc) +target_link_libraries(flex_graph_db flex_plan_proto) install_flex_target(flex_graph_db) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/database/graph_db.h @@ -32,3 +31,4 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/app/adhoc_app.h DESTINATION include/flex/engines/graph_db/app) + diff --git a/flex/engines/graph_db/app/adhoc_app.cc b/flex/engines/graph_db/app/adhoc_app.cc index a500c15cb76c..8112ee15bf8a 100644 --- a/flex/engines/graph_db/app/adhoc_app.cc +++ b/flex/engines/graph_db/app/adhoc_app.cc @@ -14,6 +14,7 @@ */ #include "flex/engines/graph_db/app/adhoc_app.h" +#include "flex/engines/graph_db/runtime/adhoc/graph_interface.h" #include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" #include "flex/engines/graph_db/runtime/adhoc/runtime.h" #include "flex/proto_generated_gie/physical.pb.h" @@ -26,7 +27,8 @@ namespace gs { bool AdhocReadApp::Query(const GraphDBSession& graph, Decoder& input, Encoder& output) { - auto txn = graph.GetReadTransaction(); + auto read_txn = graph.GetReadTransaction(); + gs::runtime::GraphInterface txn(read_txn); std::string_view plan_str = input.get_bytes(); physical::PhysicalPlan plan; diff --git a/flex/engines/graph_db/database/read_transaction.h b/flex/engines/graph_db/database/read_transaction.h index 5a88b1807f7e..6190ff805294 100644 --- a/flex/engines/graph_db/database/read_transaction.h +++ b/flex/engines/graph_db/database/read_transaction.h @@ -29,6 +29,7 @@ class MutablePropertyFragment; class VersionManager; template class AdjListView { + public: class nbr_iterator { using const_nbr_t = typename MutableNbrSlice::const_nbr_t; using const_nbr_ptr_t = typename MutableNbrSlice::const_nbr_ptr_t; @@ -68,7 +69,6 @@ class AdjListView { timestamp_t timestamp_; }; - public: using slice_t = MutableNbrSlice; AdjListView(const slice_t& slice, timestamp_t timestamp) @@ -276,6 +276,7 @@ class SingleImmutableGraphView { class ReadTransaction { public: + using vertex_index_t = vid_t; ReadTransaction(const MutablePropertyFragment& graph, VersionManager& vm, timestamp_t timestamp); ~ReadTransaction(); diff --git a/flex/engines/graph_db/runtime/CMakeLists.txt b/flex/engines/graph_db/runtime/CMakeLists.txt index 99d58d16d9ce..ea09a24b00b6 100644 --- a/flex/engines/graph_db/runtime/CMakeLists.txt +++ b/flex/engines/graph_db/runtime/CMakeLists.txt @@ -1,16 +1,5 @@ -file(GLOB_RECURSE COMMON_SOURCES "common/*.cc") -add_library(runtime_common SHARED ${COMMON_SOURCES}) -target_link_libraries(runtime_common ${Boost_LIBRARIES} flex_utils flex_plan_proto) -install_flex_target(runtime_common) - -file(GLOB_RECURSE ADHOC_SOURCES "adhoc/*.cc") -add_library(runtime_adhoc SHARED ${ADHOC_SOURCES}) -target_link_libraries(runtime_adhoc runtime_common) -install_flex_target(runtime_adhoc) - - install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DESTINATION include/flex/engines/graph_db + DESTINATION include/flex/engines/graph_db/runtime FILES_MATCHING PATTERN "*.h" ) \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/adhoc/expr.cc b/flex/engines/graph_db/runtime/adhoc/expr.cc deleted file mode 100644 index 648f7a108390..000000000000 --- a/flex/engines/graph_db/runtime/adhoc/expr.cc +++ /dev/null @@ -1,58 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/adhoc/expr.h" - -namespace gs { - -namespace runtime { - -Expr::Expr(const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr, VarType var_type) { - expr_ = parse_expression(txn, ctx, params, expr, var_type); -} - -RTAny Expr::eval_path(size_t idx) const { - RTAny ret = expr_->eval_path(idx); - return ret; -} - -RTAny Expr::eval_vertex(label_t label, vid_t v, size_t idx) const { - return expr_->eval_vertex(label, v, idx); -} -RTAny Expr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - return expr_->eval_edge(label, src, dst, data, idx); -} - -RTAny Expr::eval_path(size_t idx, int) const { - return expr_->eval_path(idx, 0); -} - -RTAny Expr::eval_vertex(label_t label, vid_t v, size_t idx, int) const { - return expr_->eval_vertex(label, v, idx, 0); -} - -RTAny Expr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx, int) const { - return expr_->eval_edge(label, src, dst, data, idx, 0); -} - -RTAnyType Expr::type() const { return expr_->type(); } - -} // namespace runtime - -} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/adhoc/expr.h b/flex/engines/graph_db/runtime/adhoc/expr.h index 13cc2eb2d1f0..2cfe3b3c6288 100644 --- a/flex/engines/graph_db/runtime/adhoc/expr.h +++ b/flex/engines/graph_db/runtime/adhoc/expr.h @@ -24,22 +24,36 @@ namespace gs { namespace runtime { +template class Expr { public: - Expr(const ReadTransaction& txn, const Context& ctx, + Expr(const GraphInterface& txn, const Context& ctx, const std::map& params, - const common::Expression& expr, VarType var_type); + const common::Expression& expr, VarType var_type) { + expr_ = parse_expression(txn, ctx, params, expr, var_type); + } - RTAny eval_path(size_t idx) const; - RTAny eval_vertex(label_t label, vid_t v, size_t idx) const; + RTAny eval_path(size_t idx) const { + RTAny ret = expr_->eval_path(idx); + return ret; + } + RTAny eval_vertex(label_t label, vid_t v, size_t idx) const { + return expr_->eval_vertex(label, v, idx); + } RTAny eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const; - RTAny eval_path(size_t idx, int) const; - RTAny eval_vertex(label_t label, vid_t v, size_t idx, int) const; + const Any& data, size_t idx) const { + return expr_->eval_edge(label, src, dst, data, idx); + } + RTAny eval_path(size_t idx, int) const { return expr_->eval_path(idx, 0); } + RTAny eval_vertex(label_t label, vid_t v, size_t idx, int) const { + return expr_->eval_vertex(label, v, idx, 0); + } RTAny eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx, int) const; + const Any& data, size_t idx, int) const { + return expr_->eval_edge(label, src, dst, data, idx, 0); + } - RTAnyType type() const; + RTAnyType type() const { return expr_->type(); } std::shared_ptr builder() const { return expr_->builder(); diff --git a/flex/engines/graph_db/runtime/adhoc/expr_impl.cc b/flex/engines/graph_db/runtime/adhoc/expr_impl.cc deleted file mode 100644 index 7df4cdbeed15..000000000000 --- a/flex/engines/graph_db/runtime/adhoc/expr_impl.cc +++ /dev/null @@ -1,724 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/adhoc/expr_impl.h" -#include -#include - -namespace gs { - -namespace runtime { - -VariableExpr::VariableExpr(const ReadTransaction& txn, const Context& ctx, - const common::Variable& pb, VarType var_type) - : var_(txn, ctx, pb, var_type) {} -RTAny VariableExpr::eval_path(size_t idx) const { return var_.get(idx); } -RTAny VariableExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { - return var_.get_vertex(label, v, idx); -} -RTAny VariableExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - return var_.get_edge(label, src, dst, data, idx); -} - -RTAny VariableExpr::eval_path(size_t idx, int) const { - return var_.get(idx, 0); -} - -RTAny VariableExpr::eval_vertex(label_t label, vid_t v, size_t idx, int) const { - return var_.get_vertex(label, v, idx, 0); -} - -RTAny VariableExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx, int) const { - return var_.get_edge(label, src, dst, data, idx, 0); -} - -RTAnyType VariableExpr::type() const { return var_.type(); } - -LogicalExpr::LogicalExpr(std::unique_ptr&& lhs, - std::unique_ptr&& rhs, common::Logical logic) - : lhs_(std::move(lhs)), rhs_(std::move(rhs)), logic_(logic) {} - -RTAny LogicalExpr::eval_path(size_t idx) const { - if (logic_ == common::Logical::LT) { - bool ret = lhs_->eval_path(idx) < rhs_->eval_path(idx); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::GT) { - bool ret = rhs_->eval_path(idx) < lhs_->eval_path(idx); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::GE) { - bool ret = lhs_->eval_path(idx) < rhs_->eval_path(idx); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::LE) { - bool ret = rhs_->eval_path(idx) < lhs_->eval_path(idx); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::EQ) { - bool ret = (rhs_->eval_path(idx) == lhs_->eval_path(idx)); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::NE) { - bool ret = (rhs_->eval_path(idx) == lhs_->eval_path(idx)); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::AND) { - bool ret = - (rhs_->eval_path(idx).as_bool() && lhs_->eval_path(idx).as_bool()); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::OR) { - bool ret = - (rhs_->eval_path(idx).as_bool() || lhs_->eval_path(idx).as_bool()); - return RTAny::from_bool(ret); - } else { - LOG(FATAL) << "not support..." << static_cast(logic_); - } - return RTAny::from_bool(false); -} - -RTAny LogicalExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { - if (logic_ == common::Logical::LT) { - bool ret = - lhs_->eval_vertex(label, v, idx) < rhs_->eval_vertex(label, v, idx); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::GT) { - bool ret = - rhs_->eval_vertex(label, v, idx) < lhs_->eval_vertex(label, v, idx); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::GE) { - bool ret = - lhs_->eval_vertex(label, v, idx) < rhs_->eval_vertex(label, v, idx); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::LE) { - bool ret = - rhs_->eval_vertex(label, v, idx) < lhs_->eval_vertex(label, v, idx); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::EQ) { - bool ret = - (rhs_->eval_vertex(label, v, idx) == lhs_->eval_vertex(label, v, idx)); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::NE) { - bool ret = - (rhs_->eval_vertex(label, v, idx) == lhs_->eval_vertex(label, v, idx)); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::AND) { - bool ret = (rhs_->eval_vertex(label, v, idx).as_bool() && - lhs_->eval_vertex(label, v, idx).as_bool()); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::REGEX) { - std::string ret(lhs_->eval_vertex(label, v, idx).as_string()); - std::string rhs(rhs_->eval_vertex(label, v, idx).as_string()); - return RTAny::from_bool(std::regex_match(ret, std::regex(rhs))); - - } else if (logic_ == common::Logical::OR) { - bool ret = (rhs_->eval_vertex(label, v, idx).as_bool() || - lhs_->eval_vertex(label, v, idx).as_bool()); - return RTAny::from_bool(ret); - } else { - LOG(FATAL) << "not support..." << static_cast(logic_); - } - return RTAny::from_bool(false); -} - -RTAny LogicalExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - if (logic_ == common::Logical::LT) { - bool ret = lhs_->eval_edge(label, src, dst, data, idx) < - rhs_->eval_edge(label, src, dst, data, idx); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::GT) { - bool ret = rhs_->eval_edge(label, src, dst, data, idx) < - lhs_->eval_edge(label, src, dst, data, idx); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::GE) { - bool ret = lhs_->eval_edge(label, src, dst, data, idx) < - rhs_->eval_edge(label, src, dst, data, idx); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::LE) { - bool ret = rhs_->eval_edge(label, src, dst, data, idx) < - lhs_->eval_edge(label, src, dst, data, idx); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::EQ) { - bool ret = (rhs_->eval_edge(label, src, dst, data, idx) == - lhs_->eval_edge(label, src, dst, data, idx)); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::NE) { - bool ret = (rhs_->eval_edge(label, src, dst, data, idx) == - lhs_->eval_edge(label, src, dst, data, idx)); - return RTAny::from_bool(!ret); - } else if (logic_ == common::Logical::AND) { - bool ret = (rhs_->eval_edge(label, src, dst, data, idx).as_bool() && - lhs_->eval_edge(label, src, dst, data, idx).as_bool()); - return RTAny::from_bool(ret); - } else if (logic_ == common::Logical::REGEX) { - std::string ret(lhs_->eval_edge(label, src, dst, data, idx).as_string()); - std::string rhs(rhs_->eval_edge(label, src, dst, data, idx).as_string()); - return RTAny::from_bool(std::regex_match(ret, std::regex(rhs))); - } else if (logic_ == common::Logical::OR) { - bool ret = (rhs_->eval_edge(label, src, dst, data, idx).as_bool() || - lhs_->eval_edge(label, src, dst, data, idx).as_bool()); - return RTAny::from_bool(ret); - } else { - LOG(FATAL) << "not support..." << static_cast(logic_); - } - return RTAny::from_bool(false); -} - -RTAnyType LogicalExpr::type() const { return RTAnyType::kBoolValue; } - -UnaryLogicalExpr::UnaryLogicalExpr(std::unique_ptr&& expr, - common::Logical logic) - : expr_(std::move(expr)), logic_(logic) {} - -RTAny UnaryLogicalExpr::eval_path(size_t idx) const { - if (logic_ == common::Logical::NOT) { - return RTAny::from_bool(!expr_->eval_path(idx).as_bool()); - } else if (logic_ == common::Logical::ISNULL) { - return RTAny::from_bool(expr_->eval_path(idx, 0).type() == - RTAnyType::kNull); - } - LOG(FATAL) << "not support" << static_cast(logic_); - return RTAny::from_bool(false); -} - -RTAny UnaryLogicalExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { - if (logic_ == common::Logical::NOT) { - return RTAny::from_bool(!expr_->eval_vertex(label, v, idx).as_bool()); - } else if (logic_ == common::Logical::ISNULL) { - return RTAny::from_bool(expr_->eval_vertex(label, v, idx, 0).is_null()); - } - LOG(FATAL) << "not support" << static_cast(logic_); - return RTAny::from_bool(false); -} - -RTAny UnaryLogicalExpr::eval_edge(const LabelTriplet& label, vid_t src, - vid_t dst, const Any& data, - size_t idx) const { - if (logic_ == common::Logical::NOT) { - return RTAny::from_bool( - !expr_->eval_edge(label, src, dst, data, idx).as_bool()); - } - LOG(FATAL) << "not support" << static_cast(logic_); - return RTAny::from_bool(false); -} - -RTAnyType UnaryLogicalExpr::type() const { return RTAnyType::kBoolValue; } - -ArithExpr::ArithExpr(std::unique_ptr&& lhs, - std::unique_ptr&& rhs, common::Arithmetic arith) - : lhs_(std::move(lhs)), rhs_(std::move(rhs)), arith_(arith) {} - -RTAny ArithExpr::eval_path(size_t idx) const { - switch (arith_) { - case common::Arithmetic::ADD: - return lhs_->eval_path(idx) + rhs_->eval_path(idx); - case common::Arithmetic::SUB: - return lhs_->eval_path(idx) - rhs_->eval_path(idx); - case common::Arithmetic::DIV: - return lhs_->eval_path(idx) / rhs_->eval_path(idx); - default: - LOG(FATAL) << "not support" << static_cast(arith_); - } - return RTAny(); -} - -RTAny ArithExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { - switch (arith_) { - case common::Arithmetic::ADD: - return lhs_->eval_path(idx) + rhs_->eval_path(idx); - default: - LOG(FATAL) << "not support"; - } - return RTAny(); -} - -RTAny ArithExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - switch (arith_) { - case common::Arithmetic::ADD: - return lhs_->eval_path(idx) + rhs_->eval_path(idx); - default: - LOG(FATAL) << "not support"; - } - return RTAny(); -} - -RTAnyType ArithExpr::type() const { return lhs_->type(); } - -ConstExpr::ConstExpr(const RTAny& val) : val_(val) { - if (val_.type() == RTAnyType::kStringValue) { - s = val_.as_string(); - val_ = RTAny::from_string(s); - } -} -RTAny ConstExpr::eval_path(size_t idx) const { return val_; } -RTAny ConstExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { - return val_; -} -RTAny ConstExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - return val_; -} - -RTAnyType ConstExpr::type() const { return val_.type(); } - -ExtractExpr::ExtractExpr(std::unique_ptr&& expr, - const common::Extract& extract) - : expr_(std::move(expr)), extract_(extract) {} - -static int32_t extract_year(int64_t ms) { - auto micro_second = ms / 1000; - struct tm tm; - gmtime_r((time_t*) (µ_second), &tm); - return tm.tm_year + 1900; -} - -static int32_t extract_month(int64_t ms) { - auto micro_second = ms / 1000; - struct tm tm; - gmtime_r((time_t*) (µ_second), &tm); - return tm.tm_mon + 1; -} - -static int32_t extract_day(int64_t ms) { - auto micro_second = ms / 1000; - struct tm tm; - gmtime_r((time_t*) (µ_second), &tm); - return tm.tm_mday; -} - -static int32_t extract_time_from_milli_second(int64_t ms, - common::Extract extract) { - if (extract.interval() == common::Extract::YEAR) { - return extract_year(ms); - } else if (extract.interval() == common::Extract::MONTH) { - return extract_month(ms); - } else if (extract.interval() == common::Extract::DAY) { - return extract_day(ms); - } else { - LOG(FATAL) << "not support"; - } - return 0; -} - -RTAny ExtractExpr::eval_path(size_t idx) const { - auto ms = expr_->eval_path(idx).as_date32(); - int32_t val = extract_time_from_milli_second(ms, extract_); - return RTAny::from_int32(val); -} - -RTAny ExtractExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { - auto ms = expr_->eval_vertex(label, v, idx).as_date32(); - int32_t val = extract_time_from_milli_second(ms, extract_); - return RTAny::from_int32(val); -} - -RTAny ExtractExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - auto ms = expr_->eval_edge(label, src, dst, data, idx).as_date32(); - int32_t val = extract_time_from_milli_second(ms, extract_); - return RTAny::from_int32(val); -} - -RTAnyType ExtractExpr::type() const { return RTAnyType::kI32Value; } - -CaseWhenExpr::CaseWhenExpr( - std::vector, - std::unique_ptr>>&& when_then_exprs, - std::unique_ptr&& else_expr) - : when_then_exprs_(std::move(when_then_exprs)), - else_expr_(std::move(else_expr)) {} - -RTAny CaseWhenExpr::eval_path(size_t idx) const { - for (auto& pair : when_then_exprs_) { - if (pair.first->eval_path(idx).as_bool()) { - return pair.second->eval_path(idx); - } - } - return else_expr_->eval_path(idx); -} - -RTAny CaseWhenExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { - for (auto& pair : when_then_exprs_) { - if (pair.first->eval_vertex(label, v, idx).as_bool()) { - return pair.second->eval_vertex(label, v, idx); - } - } - return else_expr_->eval_vertex(label, v, idx); -} - -RTAny CaseWhenExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - for (auto& pair : when_then_exprs_) { - if (pair.first->eval_edge(label, src, dst, data, idx).as_bool()) { - return pair.second->eval_edge(label, src, dst, data, idx); - } - } - return else_expr_->eval_edge(label, src, dst, data, idx); -} - -RTAnyType CaseWhenExpr::type() const { - RTAnyType type; - bool null_able = false; - if (when_then_exprs_.size() > 0) { - if (when_then_exprs_[0].second->type() == RTAnyType::kNull) { - null_able = true; - } else { - type = when_then_exprs_[0].second->type(); - } - } - if (else_expr_->type() == RTAnyType::kNull) { - null_able = true; - } else { - type = else_expr_->type(); - } - type.null_able_ = null_able; - return type; -} - -TupleExpr::TupleExpr(std::vector>&& exprs) - : exprs_(std::move(exprs)) {} - -RTAny TupleExpr::eval_path(size_t idx) const { - std::vector ret; - for (auto& expr : exprs_) { - ret.push_back(expr->eval_path(idx)); - } - return RTAny::from_tuple(std::move(ret)); -} - -RTAny TupleExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { - std::vector ret; - for (auto& expr : exprs_) { - ret.push_back(expr->eval_vertex(label, v, idx)); - } - return RTAny::from_tuple(std::move(ret)); -} - -RTAny TupleExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - std::vector ret; - for (auto& expr : exprs_) { - ret.push_back(expr->eval_edge(label, src, dst, data, idx)); - } - return RTAny::from_tuple(std::move(ret)); -} - -RTAnyType TupleExpr::type() const { return RTAnyType::kTuple; } - -static RTAny parse_const_value(const common::Value& val) { - switch (val.item_case()) { - case common::Value::kI32: - return RTAny::from_int32(val.i32()); - case common::Value::kStr: - return RTAny::from_string(val.str()); - case common::Value::kI64: - return RTAny::from_int64(val.i64()); - case common::Value::kBoolean: - return RTAny::from_bool(val.boolean()); - case common::Value::kNone: - return RTAny(RTAnyType::kNull); - case common::Value::kF64: - return RTAny::from_double(val.f64()); - default: - LOG(FATAL) << "not support for " << val.item_case(); - } - return RTAny(); -} - -static RTAny parse_param(const common::DynamicParam& param, - const std::map& input) { - if (param.data_type().type_case() == - common::IrDataType::TypeCase::kDataType) { - common::DataType dt = param.data_type().data_type(); - const std::string& name = param.name(); - if (dt == common::DataType::DATE32) { - int64_t val = std::stoll(input.at(name)); - return RTAny::from_int64(val); - } else if (dt == common::DataType::STRING) { - const std::string& val = input.at(name); - return RTAny::from_string(val); - } else if (dt == common::DataType::INT32) { - int val = std::stoi(input.at(name)); - return RTAny::from_int32(val); - } else if (dt == common::DataType::INT64) { - int64_t val = std::stoll(input.at(name)); - return RTAny::from_int64(val); - } - - LOG(FATAL) << "not support type: " << common::DataType_Name(dt); - } - LOG(FATAL) << "graph data type not expected...."; - return RTAny(); -} - -static inline int get_proiority(const common::ExprOpr& opr) { - switch (opr.item_case()) { - case common::ExprOpr::kBrace: { - return 17; - } - case common::ExprOpr::kExtract: { - return 2; - } - case common::ExprOpr::kLogical: { - switch (opr.logical()) { - case common::Logical::AND: - return 11; - case common::Logical::OR: - return 12; - case common::Logical::NOT: - return 2; - case common::Logical::WITHIN: - case common::Logical::WITHOUT: - return 2; - case common::Logical::EQ: - case common::Logical::NE: - return 7; - case common::Logical::GE: - case common::Logical::GT: - case common::Logical::LT: - case common::Logical::LE: - return 6; - case common::Logical::REGEX: - return 2; - default: - return 16; - } - } - case common::ExprOpr::kArith: { - switch (opr.arith()) { - case common::Arithmetic::ADD: - case common::Arithmetic::SUB: - return 4; - case common::Arithmetic::MUL: - case common::Arithmetic::DIV: - case common::Arithmetic::MOD: - return 3; - default: - return 16; - } - } - default: - return 16; - } - return 16; -} -static std::unique_ptr parse_expression_impl( - const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr, VarType var_type); -static std::unique_ptr build_expr( - const ReadTransaction& txn, const Context& ctx, - const std::map& params, - std::stack& opr_stack, VarType var_type) { - while (!opr_stack.empty()) { - auto opr = opr_stack.top(); - opr_stack.pop(); - switch (opr.item_case()) { - case common::ExprOpr::kConst: { - if (opr.const_().item_case() == common::Value::kStr) { - const std::string& str = opr.const_().str(); - return std::make_unique(RTAny::from_string(str)); - } - return std::make_unique(parse_const_value(opr.const_())); - } - case common::ExprOpr::kParam: { - return std::make_unique(parse_param(opr.param(), params)); - } - case common::ExprOpr::kVar: { - return std::make_unique(txn, ctx, opr.var(), var_type); - } - case common::ExprOpr::kLogical: { - if (opr.logical() == common::Logical::WITHIN) { - auto lhs = opr_stack.top(); - opr_stack.pop(); - auto rhs = opr_stack.top(); - opr_stack.pop(); - CHECK(lhs.has_var()); - CHECK(rhs.has_const_()); - auto key = - std::make_unique(txn, ctx, lhs.var(), var_type); - if (key->type() == RTAnyType::kI64Value) { - return std::make_unique>(txn, ctx, std::move(key), - rhs.const_()); - } else if (key->type() == RTAnyType::kI32Value) { - return std::make_unique>(txn, ctx, std::move(key), - rhs.const_()); - } else if (key->type() == RTAnyType::kStringValue) { - return std::make_unique>( - txn, ctx, std::move(key), rhs.const_()); - } else { - LOG(FATAL) << "not support"; - } - } else if (opr.logical() == common::Logical::NOT || - opr.logical() == common::Logical::ISNULL) { - auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); - return std::make_unique(std::move(lhs), - opr.logical()); - } else { - auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); - auto rhs = build_expr(txn, ctx, params, opr_stack, var_type); - return std::make_unique(std::move(lhs), std::move(rhs), - opr.logical()); - } - break; - } - case common::ExprOpr::kArith: { - auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); - auto rhs = build_expr(txn, ctx, params, opr_stack, var_type); - return std::make_unique(std::move(lhs), std::move(rhs), - opr.arith()); - } - case common::ExprOpr::kCase: { - auto op = opr.case_(); - size_t len = op.when_then_expressions_size(); - std::vector< - std::pair, std::unique_ptr>> - when_then_exprs; - for (size_t i = 0; i < len; ++i) { - auto when_expr = op.when_then_expressions(i).when_expression(); - auto then_expr = op.when_then_expressions(i).then_result_expression(); - when_then_exprs.emplace_back( - parse_expression_impl(txn, ctx, params, when_expr, var_type), - parse_expression_impl(txn, ctx, params, then_expr, var_type)); - } - auto else_expr = parse_expression_impl( - txn, ctx, params, op.else_result_expression(), var_type); - return std::make_unique(std::move(when_then_exprs), - std::move(else_expr)); - } - case common::ExprOpr::kExtract: { - auto hs = build_expr(txn, ctx, params, opr_stack, var_type); - return std::make_unique(std::move(hs), opr.extract()); - } - case common::ExprOpr::kVars: { - auto op = opr.vars(); - std::vector> exprs; - for (int i = 0; i < op.keys_size(); ++i) { - exprs.push_back( - std::make_unique(txn, ctx, op.keys(i), var_type)); - } - return std::make_unique(std::move(exprs)); - // LOG(FATAL) << "not support" << opr.DebugString(); - // break; - } - case common::ExprOpr::kMap: { - auto op = opr.map(); - std::vector keys_vec; - std::vector> exprs; - for (int i = 0; i < op.key_vals_size(); ++i) { - auto key = op.key_vals(i).key(); - auto val = op.key_vals(i).val(); - auto any = parse_const_value(key); - CHECK(any.type() == RTAnyType::kStringValue); - { - auto str = any.as_string(); - keys_vec.push_back(std::string(str)); - } - exprs.emplace_back( - std::make_unique(txn, ctx, val, - var_type)); // just for parse - } - if (exprs.size() > 0) { - return std::make_unique(std::move(keys_vec), std::move(exprs)); - } - LOG(FATAL) << "not support" << opr.DebugString(); - } - default: - LOG(FATAL) << "not support" << opr.DebugString(); - break; - } - } - return nullptr; -} -static std::unique_ptr parse_expression_impl( - const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr, VarType var_type) { - std::stack opr_stack; - std::stack opr_stack2; - const auto& oprs = expr.operators(); - for (auto it = oprs.rbegin(); it != oprs.rend(); ++it) { - switch ((*it).item_case()) { - case common::ExprOpr::kBrace: { - auto brace = (*it).brace(); - if (brace == common::ExprOpr::Brace::ExprOpr_Brace_LEFT_BRACE) { - while (!opr_stack.empty() && - opr_stack.top().item_case() != common::ExprOpr::kBrace) { - opr_stack2.push(opr_stack.top()); - opr_stack.pop(); - } - CHECK(!opr_stack.empty()); - opr_stack.pop(); - } else if (brace == common::ExprOpr::Brace::ExprOpr_Brace_RIGHT_BRACE) { - opr_stack.emplace(*it); - } - break; - } - case common::ExprOpr::kConst: - case common::ExprOpr::kVar: - case common::ExprOpr::kParam: - case common::ExprOpr::kVars: { - opr_stack2.push(*it); - break; - } - case common::ExprOpr::kArith: - case common::ExprOpr::kLogical: { - // unary operator - if ((*it).logical() == common::Logical::NOT || - (*it).logical() == common::Logical::ISNULL) { - opr_stack2.push(*it); - break; - } - - while (!opr_stack.empty() && - get_proiority(opr_stack.top()) <= get_proiority(*it)) { - opr_stack2.push(opr_stack.top()); - opr_stack.pop(); - } - opr_stack.push(*it); - break; - } - case common::ExprOpr::kExtract: { - opr_stack2.push(*it); - break; - } - case common::ExprOpr::kCase: { - opr_stack2.push(*it); - break; - } - case common::ExprOpr::kMap: { - opr_stack2.push(*it); - break; - } - default: { - LOG(FATAL) << "not support" << (*it).DebugString(); - break; - } - } - } - while (!opr_stack.empty()) { - opr_stack2.push(opr_stack.top()); - opr_stack.pop(); - } - return build_expr(txn, ctx, params, opr_stack2, var_type); -} -std::unique_ptr parse_expression( - const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr, VarType var_type) { - return parse_expression_impl(txn, ctx, params, expr, var_type); -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/adhoc/expr_impl.h b/flex/engines/graph_db/runtime/adhoc/expr_impl.h index 20a764de0696..2f118dfe7238 100644 --- a/flex/engines/graph_db/runtime/adhoc/expr_impl.h +++ b/flex/engines/graph_db/runtime/adhoc/expr_impl.h @@ -16,8 +16,11 @@ #ifndef RUNTIME_ADHOC_RUNTIME_EXPR_IMPL_H_ #define RUNTIME_ADHOC_RUNTIME_EXPR_IMPL_H_ +#include +#include #include "flex/proto_generated_gie/expr.pb.h" +#include "flex/engines/graph_db/runtime/adhoc/graph_interface.h" #include "flex/engines/graph_db/runtime/adhoc/var.h" #include "flex/engines/graph_db/runtime/common/rt_any.h" @@ -79,10 +82,10 @@ class ConstFalseExpr : public ExprBase { RTAnyType type() const override { return RTAnyType::kBoolValue; } }; -template +template class WithInExpr : public ExprBase { public: - WithInExpr(const ReadTransaction& txn, const Context& ctx, + WithInExpr(const GraphInterface& txn, const Context& ctx, std::unique_ptr&& key, const common::Value& array) : key_(std::move(key)) { if constexpr (std::is_same_v) { @@ -169,21 +172,32 @@ class WithInExpr : public ExprBase { std::vector container_; }; +template class VariableExpr : public ExprBase { public: - VariableExpr(const ReadTransaction& txn, const Context& ctx, - const common::Variable& pb, VarType var_type); + VariableExpr(const GraphInterface& txn, const Context& ctx, + const common::Variable& pb, VarType var_type) + : var_(txn, ctx, pb, var_type) {} - RTAny eval_path(size_t idx) const override; - RTAny eval_vertex(label_t label, vid_t v, size_t idx) const override; + RTAny eval_path(size_t idx) const override { return var_.get(idx); } + RTAny eval_vertex(label_t label, vid_t v, size_t idx) const override { + return var_.get_vertex(label, v, idx); + } RTAny eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const override; - RTAnyType type() const override; + const Any& data, size_t idx) const override { + return var_.get_edge(label, src, dst, data, idx); + } + RTAnyType type() const override { return var_.type(); } + + RTAny eval_path(size_t idx, int) const override { return var_.get(idx, 0); } + RTAny eval_vertex(label_t label, vid_t v, size_t idx, int) const override { + return var_.get_vertex(label, v, idx, 0); + } - RTAny eval_path(size_t idx, int) const override; - RTAny eval_vertex(label_t label, vid_t v, size_t idx, int) const override; RTAny eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx, int) const override; + const Any& data, size_t idx, int) const override { + return var_.get_edge(label, src, dst, data, idx, 0); + } std::shared_ptr builder() const override { return var_.builder(); @@ -192,7 +206,7 @@ class VariableExpr : public ExprBase { bool is_optional() const override { return var_.is_optional(); } private: - Var var_; + Var var_; }; class UnaryLogicalExpr : public ExprBase { @@ -239,6 +253,7 @@ class LogicalExpr : public ExprBase { RTAny eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, const Any& data, size_t idx, int) const override { LOG(FATAL) << "not implemented"; + return RTAny(); } RTAnyType type() const override; @@ -399,10 +414,679 @@ class MapExpr : public ExprBase { std::vector> value_exprs; mutable std::vector> values; }; + +LogicalExpr::LogicalExpr(std::unique_ptr&& lhs, + std::unique_ptr&& rhs, common::Logical logic) + : lhs_(std::move(lhs)), rhs_(std::move(rhs)), logic_(logic) {} + +RTAny LogicalExpr::eval_path(size_t idx) const { + if (logic_ == common::Logical::LT) { + bool ret = lhs_->eval_path(idx) < rhs_->eval_path(idx); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::GT) { + bool ret = rhs_->eval_path(idx) < lhs_->eval_path(idx); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::GE) { + bool ret = lhs_->eval_path(idx) < rhs_->eval_path(idx); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::LE) { + bool ret = rhs_->eval_path(idx) < lhs_->eval_path(idx); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::EQ) { + bool ret = (rhs_->eval_path(idx) == lhs_->eval_path(idx)); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::NE) { + bool ret = (rhs_->eval_path(idx) == lhs_->eval_path(idx)); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::AND) { + bool ret = + (rhs_->eval_path(idx).as_bool() && lhs_->eval_path(idx).as_bool()); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::OR) { + bool ret = + (rhs_->eval_path(idx).as_bool() || lhs_->eval_path(idx).as_bool()); + return RTAny::from_bool(ret); + } else { + LOG(FATAL) << "not support..." << static_cast(logic_); + } + return RTAny::from_bool(false); +} + +RTAny LogicalExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { + if (logic_ == common::Logical::LT) { + bool ret = + lhs_->eval_vertex(label, v, idx) < rhs_->eval_vertex(label, v, idx); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::GT) { + bool ret = + rhs_->eval_vertex(label, v, idx) < lhs_->eval_vertex(label, v, idx); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::GE) { + bool ret = + lhs_->eval_vertex(label, v, idx) < rhs_->eval_vertex(label, v, idx); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::LE) { + bool ret = + rhs_->eval_vertex(label, v, idx) < lhs_->eval_vertex(label, v, idx); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::EQ) { + bool ret = + (rhs_->eval_vertex(label, v, idx) == lhs_->eval_vertex(label, v, idx)); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::NE) { + bool ret = + (rhs_->eval_vertex(label, v, idx) == lhs_->eval_vertex(label, v, idx)); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::AND) { + bool ret = (rhs_->eval_vertex(label, v, idx).as_bool() && + lhs_->eval_vertex(label, v, idx).as_bool()); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::REGEX) { + std::string ret(lhs_->eval_vertex(label, v, idx).as_string()); + std::string rhs(rhs_->eval_vertex(label, v, idx).as_string()); + return RTAny::from_bool(std::regex_match(ret, std::regex(rhs))); + + } else if (logic_ == common::Logical::OR) { + bool ret = (rhs_->eval_vertex(label, v, idx).as_bool() || + lhs_->eval_vertex(label, v, idx).as_bool()); + return RTAny::from_bool(ret); + } else { + LOG(FATAL) << "not support..." << static_cast(logic_); + } + return RTAny::from_bool(false); +} + +RTAny LogicalExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, + const Any& data, size_t idx) const { + if (logic_ == common::Logical::LT) { + bool ret = lhs_->eval_edge(label, src, dst, data, idx) < + rhs_->eval_edge(label, src, dst, data, idx); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::GT) { + bool ret = rhs_->eval_edge(label, src, dst, data, idx) < + lhs_->eval_edge(label, src, dst, data, idx); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::GE) { + bool ret = lhs_->eval_edge(label, src, dst, data, idx) < + rhs_->eval_edge(label, src, dst, data, idx); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::LE) { + bool ret = rhs_->eval_edge(label, src, dst, data, idx) < + lhs_->eval_edge(label, src, dst, data, idx); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::EQ) { + bool ret = (rhs_->eval_edge(label, src, dst, data, idx) == + lhs_->eval_edge(label, src, dst, data, idx)); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::NE) { + bool ret = (rhs_->eval_edge(label, src, dst, data, idx) == + lhs_->eval_edge(label, src, dst, data, idx)); + return RTAny::from_bool(!ret); + } else if (logic_ == common::Logical::AND) { + bool ret = (rhs_->eval_edge(label, src, dst, data, idx).as_bool() && + lhs_->eval_edge(label, src, dst, data, idx).as_bool()); + return RTAny::from_bool(ret); + } else if (logic_ == common::Logical::REGEX) { + std::string ret(lhs_->eval_edge(label, src, dst, data, idx).as_string()); + std::string rhs(rhs_->eval_edge(label, src, dst, data, idx).as_string()); + return RTAny::from_bool(std::regex_match(ret, std::regex(rhs))); + } else if (logic_ == common::Logical::OR) { + bool ret = (rhs_->eval_edge(label, src, dst, data, idx).as_bool() || + lhs_->eval_edge(label, src, dst, data, idx).as_bool()); + return RTAny::from_bool(ret); + } else { + LOG(FATAL) << "not support..." << static_cast(logic_); + } + return RTAny::from_bool(false); +} + +RTAnyType LogicalExpr::type() const { return RTAnyType::kBoolValue; } + +UnaryLogicalExpr::UnaryLogicalExpr(std::unique_ptr&& expr, + common::Logical logic) + : expr_(std::move(expr)), logic_(logic) {} + +RTAny UnaryLogicalExpr::eval_path(size_t idx) const { + if (logic_ == common::Logical::NOT) { + return RTAny::from_bool(!expr_->eval_path(idx).as_bool()); + } else if (logic_ == common::Logical::ISNULL) { + return RTAny::from_bool(expr_->eval_path(idx, 0).type() == + RTAnyType::kNull); + } + LOG(FATAL) << "not support" << static_cast(logic_); + return RTAny::from_bool(false); +} + +RTAny UnaryLogicalExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { + if (logic_ == common::Logical::NOT) { + return RTAny::from_bool(!expr_->eval_vertex(label, v, idx).as_bool()); + } else if (logic_ == common::Logical::ISNULL) { + return RTAny::from_bool(expr_->eval_vertex(label, v, idx, 0).is_null()); + } + LOG(FATAL) << "not support" << static_cast(logic_); + return RTAny::from_bool(false); +} + +RTAny UnaryLogicalExpr::eval_edge(const LabelTriplet& label, vid_t src, + vid_t dst, const Any& data, + size_t idx) const { + if (logic_ == common::Logical::NOT) { + return RTAny::from_bool( + !expr_->eval_edge(label, src, dst, data, idx).as_bool()); + } + LOG(FATAL) << "not support" << static_cast(logic_); + return RTAny::from_bool(false); +} + +RTAnyType UnaryLogicalExpr::type() const { return RTAnyType::kBoolValue; } + +ArithExpr::ArithExpr(std::unique_ptr&& lhs, + std::unique_ptr&& rhs, common::Arithmetic arith) + : lhs_(std::move(lhs)), rhs_(std::move(rhs)), arith_(arith) {} + +RTAny ArithExpr::eval_path(size_t idx) const { + switch (arith_) { + case common::Arithmetic::ADD: + return lhs_->eval_path(idx) + rhs_->eval_path(idx); + case common::Arithmetic::SUB: + return lhs_->eval_path(idx) - rhs_->eval_path(idx); + case common::Arithmetic::DIV: + return lhs_->eval_path(idx) / rhs_->eval_path(idx); + default: + LOG(FATAL) << "not support" << static_cast(arith_); + } + return RTAny(); +} + +RTAny ArithExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { + switch (arith_) { + case common::Arithmetic::ADD: + return lhs_->eval_path(idx) + rhs_->eval_path(idx); + default: + LOG(FATAL) << "not support"; + } + return RTAny(); +} + +RTAny ArithExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, + const Any& data, size_t idx) const { + switch (arith_) { + case common::Arithmetic::ADD: + return lhs_->eval_path(idx) + rhs_->eval_path(idx); + default: + LOG(FATAL) << "not support"; + } + return RTAny(); +} + +RTAnyType ArithExpr::type() const { return lhs_->type(); } + +ConstExpr::ConstExpr(const RTAny& val) : val_(val) { + if (val_.type() == RTAnyType::kStringValue) { + s = val_.as_string(); + val_ = RTAny::from_string(s); + } +} +RTAny ConstExpr::eval_path(size_t idx) const { return val_; } +RTAny ConstExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { + return val_; +} +RTAny ConstExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, + const Any& data, size_t idx) const { + return val_; +} + +RTAnyType ConstExpr::type() const { return val_.type(); } + +ExtractExpr::ExtractExpr(std::unique_ptr&& expr, + const common::Extract& extract) + : expr_(std::move(expr)), extract_(extract) {} + +static int32_t extract_year(int64_t ms) { + auto micro_second = ms / 1000; + struct tm tm; + gmtime_r((time_t*) (µ_second), &tm); + return tm.tm_year + 1900; +} + +static int32_t extract_month(int64_t ms) { + auto micro_second = ms / 1000; + struct tm tm; + gmtime_r((time_t*) (µ_second), &tm); + return tm.tm_mon + 1; +} + +static int32_t extract_day(int64_t ms) { + auto micro_second = ms / 1000; + struct tm tm; + gmtime_r((time_t*) (µ_second), &tm); + return tm.tm_mday; +} + +static int32_t extract_time_from_milli_second(int64_t ms, + common::Extract extract) { + if (extract.interval() == common::Extract::YEAR) { + return extract_year(ms); + } else if (extract.interval() == common::Extract::MONTH) { + return extract_month(ms); + } else if (extract.interval() == common::Extract::DAY) { + return extract_day(ms); + } else { + LOG(FATAL) << "not support"; + } + return 0; +} + +RTAny ExtractExpr::eval_path(size_t idx) const { + auto ms = expr_->eval_path(idx).as_date32(); + int32_t val = extract_time_from_milli_second(ms, extract_); + return RTAny::from_int32(val); +} + +RTAny ExtractExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { + auto ms = expr_->eval_vertex(label, v, idx).as_date32(); + int32_t val = extract_time_from_milli_second(ms, extract_); + return RTAny::from_int32(val); +} + +RTAny ExtractExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, + const Any& data, size_t idx) const { + auto ms = expr_->eval_edge(label, src, dst, data, idx).as_date32(); + int32_t val = extract_time_from_milli_second(ms, extract_); + return RTAny::from_int32(val); +} + +RTAnyType ExtractExpr::type() const { return RTAnyType::kI32Value; } + +CaseWhenExpr::CaseWhenExpr( + std::vector, + std::unique_ptr>>&& when_then_exprs, + std::unique_ptr&& else_expr) + : when_then_exprs_(std::move(when_then_exprs)), + else_expr_(std::move(else_expr)) {} + +RTAny CaseWhenExpr::eval_path(size_t idx) const { + for (auto& pair : when_then_exprs_) { + if (pair.first->eval_path(idx).as_bool()) { + return pair.second->eval_path(idx); + } + } + return else_expr_->eval_path(idx); +} + +RTAny CaseWhenExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { + for (auto& pair : when_then_exprs_) { + if (pair.first->eval_vertex(label, v, idx).as_bool()) { + return pair.second->eval_vertex(label, v, idx); + } + } + return else_expr_->eval_vertex(label, v, idx); +} + +RTAny CaseWhenExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, + const Any& data, size_t idx) const { + for (auto& pair : when_then_exprs_) { + if (pair.first->eval_edge(label, src, dst, data, idx).as_bool()) { + return pair.second->eval_edge(label, src, dst, data, idx); + } + } + return else_expr_->eval_edge(label, src, dst, data, idx); +} + +RTAnyType CaseWhenExpr::type() const { + RTAnyType type; + bool null_able = false; + if (when_then_exprs_.size() > 0) { + if (when_then_exprs_[0].second->type() == RTAnyType::kNull) { + null_able = true; + } else { + type = when_then_exprs_[0].second->type(); + } + } + if (else_expr_->type() == RTAnyType::kNull) { + null_able = true; + } else { + type = else_expr_->type(); + } + type.null_able_ = null_able; + return type; +} + +TupleExpr::TupleExpr(std::vector>&& exprs) + : exprs_(std::move(exprs)) {} + +RTAny TupleExpr::eval_path(size_t idx) const { + std::vector ret; + for (auto& expr : exprs_) { + ret.push_back(expr->eval_path(idx)); + } + return RTAny::from_tuple(std::move(ret)); +} + +RTAny TupleExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { + std::vector ret; + for (auto& expr : exprs_) { + ret.push_back(expr->eval_vertex(label, v, idx)); + } + return RTAny::from_tuple(std::move(ret)); +} + +RTAny TupleExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, + const Any& data, size_t idx) const { + std::vector ret; + for (auto& expr : exprs_) { + ret.push_back(expr->eval_edge(label, src, dst, data, idx)); + } + return RTAny::from_tuple(std::move(ret)); +} + +RTAnyType TupleExpr::type() const { return RTAnyType::kTuple; } + +static RTAny parse_const_value(const common::Value& val) { + switch (val.item_case()) { + case common::Value::kI32: + return RTAny::from_int32(val.i32()); + case common::Value::kStr: + return RTAny::from_string(val.str()); + case common::Value::kI64: + return RTAny::from_int64(val.i64()); + case common::Value::kBoolean: + return RTAny::from_bool(val.boolean()); + case common::Value::kNone: + return RTAny(RTAnyType::kNull); + case common::Value::kF64: + return RTAny::from_double(val.f64()); + default: + LOG(FATAL) << "not support for " << val.item_case(); + } + return RTAny(); +} + +static RTAny parse_param(const common::DynamicParam& param, + const std::map& input) { + if (param.data_type().type_case() == + common::IrDataType::TypeCase::kDataType) { + common::DataType dt = param.data_type().data_type(); + const std::string& name = param.name(); + if (dt == common::DataType::DATE32) { + int64_t val = std::stoll(input.at(name)); + return RTAny::from_int64(val); + } else if (dt == common::DataType::STRING) { + const std::string& val = input.at(name); + return RTAny::from_string(val); + } else if (dt == common::DataType::INT32) { + int val = std::stoi(input.at(name)); + return RTAny::from_int32(val); + } else if (dt == common::DataType::INT64) { + int64_t val = std::stoll(input.at(name)); + return RTAny::from_int64(val); + } + + LOG(FATAL) << "not support type: " << common::DataType_Name(dt); + } + LOG(FATAL) << "graph data type not expected...."; + return RTAny(); +} + +static inline int get_proiority(const common::ExprOpr& opr) { + switch (opr.item_case()) { + case common::ExprOpr::kBrace: { + return 17; + } + case common::ExprOpr::kExtract: { + return 2; + } + case common::ExprOpr::kLogical: { + switch (opr.logical()) { + case common::Logical::AND: + return 11; + case common::Logical::OR: + return 12; + case common::Logical::NOT: + return 2; + case common::Logical::WITHIN: + case common::Logical::WITHOUT: + return 2; + case common::Logical::EQ: + case common::Logical::NE: + return 7; + case common::Logical::GE: + case common::Logical::GT: + case common::Logical::LT: + case common::Logical::LE: + return 6; + case common::Logical::REGEX: + return 2; + default: + return 16; + } + } + case common::ExprOpr::kArith: { + switch (opr.arith()) { + case common::Arithmetic::ADD: + case common::Arithmetic::SUB: + return 4; + case common::Arithmetic::MUL: + case common::Arithmetic::DIV: + case common::Arithmetic::MOD: + return 3; + default: + return 16; + } + } + default: + return 16; + } + return 16; +} + +template +static std::unique_ptr build_expr( + const GraphInterface& txn, const Context& ctx, + const std::map& params, + std::stack& opr_stack, VarType var_type) { + while (!opr_stack.empty()) { + auto opr = opr_stack.top(); + opr_stack.pop(); + switch (opr.item_case()) { + case common::ExprOpr::kConst: { + if (opr.const_().item_case() == common::Value::kStr) { + const std::string& str = opr.const_().str(); + return std::make_unique(RTAny::from_string(str)); + } + return std::make_unique(parse_const_value(opr.const_())); + } + case common::ExprOpr::kParam: { + return std::make_unique(parse_param(opr.param(), params)); + } + case common::ExprOpr::kVar: { + return std::make_unique>(txn, ctx, opr.var(), + var_type); + } + case common::ExprOpr::kLogical: { + if (opr.logical() == common::Logical::WITHIN) { + auto lhs = opr_stack.top(); + opr_stack.pop(); + auto rhs = opr_stack.top(); + opr_stack.pop(); + CHECK(lhs.has_var()); + CHECK(rhs.has_const_()); + auto key = std::make_unique>( + txn, ctx, lhs.var(), var_type); + if (key->type() == RTAnyType::kI64Value) { + return std::make_unique>( + txn, ctx, std::move(key), rhs.const_()); + } else if (key->type() == RTAnyType::kI32Value) { + return std::make_unique>( + txn, ctx, std::move(key), rhs.const_()); + } else if (key->type() == RTAnyType::kStringValue) { + return std::make_unique>( + txn, ctx, std::move(key), rhs.const_()); + } else { + LOG(FATAL) << "not support"; + } + } else if (opr.logical() == common::Logical::NOT || + opr.logical() == common::Logical::ISNULL) { + auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); + return std::make_unique(std::move(lhs), + opr.logical()); + } else { + auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); + auto rhs = build_expr(txn, ctx, params, opr_stack, var_type); + return std::make_unique(std::move(lhs), std::move(rhs), + opr.logical()); + } + break; + } + case common::ExprOpr::kArith: { + auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); + auto rhs = build_expr(txn, ctx, params, opr_stack, var_type); + return std::make_unique(std::move(lhs), std::move(rhs), + opr.arith()); + } + case common::ExprOpr::kCase: { + auto op = opr.case_(); + size_t len = op.when_then_expressions_size(); + std::vector< + std::pair, std::unique_ptr>> + when_then_exprs; + for (size_t i = 0; i < len; ++i) { + auto when_expr = op.when_then_expressions(i).when_expression(); + auto then_expr = op.when_then_expressions(i).then_result_expression(); + when_then_exprs.emplace_back( + parse_expression_impl(txn, ctx, params, when_expr, var_type), + parse_expression_impl(txn, ctx, params, then_expr, var_type)); + } + auto else_expr = parse_expression_impl( + txn, ctx, params, op.else_result_expression(), var_type); + return std::make_unique(std::move(when_then_exprs), + std::move(else_expr)); + } + case common::ExprOpr::kExtract: { + auto hs = build_expr(txn, ctx, params, opr_stack, var_type); + return std::make_unique(std::move(hs), opr.extract()); + } + case common::ExprOpr::kVars: { + auto op = opr.vars(); + std::vector> exprs; + for (int i = 0; i < op.keys_size(); ++i) { + exprs.push_back(std::make_unique>( + txn, ctx, op.keys(i), var_type)); + } + return std::make_unique(std::move(exprs)); + // LOG(FATAL) << "not support" << opr.DebugString(); + // break; + } + case common::ExprOpr::kMap: { + auto op = opr.map(); + std::vector keys_vec; + std::vector> exprs; + for (int i = 0; i < op.key_vals_size(); ++i) { + auto key = op.key_vals(i).key(); + auto val = op.key_vals(i).val(); + auto any = parse_const_value(key); + CHECK(any.type() == RTAnyType::kStringValue); + { + auto str = any.as_string(); + keys_vec.push_back(std::string(str)); + } + exprs.emplace_back(std::make_unique>( + txn, ctx, val, + var_type)); // just for parse + } + if (exprs.size() > 0) { + return std::make_unique(std::move(keys_vec), std::move(exprs)); + } + LOG(FATAL) << "not support" << opr.DebugString(); + } + default: + LOG(FATAL) << "not support" << opr.DebugString(); + break; + } + } + return nullptr; +} +template +static std::unique_ptr parse_expression_impl( + const GraphInterface& txn, const Context& ctx, + const std::map& params, + const common::Expression& expr, VarType var_type) { + std::stack opr_stack; + std::stack opr_stack2; + const auto& oprs = expr.operators(); + for (auto it = oprs.rbegin(); it != oprs.rend(); ++it) { + switch ((*it).item_case()) { + case common::ExprOpr::kBrace: { + auto brace = (*it).brace(); + if (brace == common::ExprOpr::Brace::ExprOpr_Brace_LEFT_BRACE) { + while (!opr_stack.empty() && + opr_stack.top().item_case() != common::ExprOpr::kBrace) { + opr_stack2.push(opr_stack.top()); + opr_stack.pop(); + } + CHECK(!opr_stack.empty()); + opr_stack.pop(); + } else if (brace == common::ExprOpr::Brace::ExprOpr_Brace_RIGHT_BRACE) { + opr_stack.emplace(*it); + } + break; + } + case common::ExprOpr::kConst: + case common::ExprOpr::kVar: + case common::ExprOpr::kParam: + case common::ExprOpr::kVars: { + opr_stack2.push(*it); + break; + } + case common::ExprOpr::kArith: + case common::ExprOpr::kLogical: { + // unary operator + if ((*it).logical() == common::Logical::NOT || + (*it).logical() == common::Logical::ISNULL) { + opr_stack2.push(*it); + break; + } + + while (!opr_stack.empty() && + get_proiority(opr_stack.top()) <= get_proiority(*it)) { + opr_stack2.push(opr_stack.top()); + opr_stack.pop(); + } + opr_stack.push(*it); + break; + } + case common::ExprOpr::kExtract: { + opr_stack2.push(*it); + break; + } + case common::ExprOpr::kCase: { + opr_stack2.push(*it); + break; + } + case common::ExprOpr::kMap: { + opr_stack2.push(*it); + break; + } + default: { + LOG(FATAL) << "not support" << (*it).DebugString(); + break; + } + } + } + while (!opr_stack.empty()) { + opr_stack2.push(opr_stack.top()); + opr_stack.pop(); + } + return build_expr(txn, ctx, params, opr_stack2, var_type); +} + +template std::unique_ptr parse_expression( - const ReadTransaction& txn, const Context& ctx, + const GraphInterface& txn, const Context& ctx, const std::map& params, - const common::Expression& expr, VarType var_type); + const common::Expression& expr, VarType var_type) { + return parse_expression_impl(txn, ctx, params, expr, var_type); +} } // namespace runtime diff --git a/flex/engines/graph_db/runtime/adhoc/graph_interface.h b/flex/engines/graph_db/runtime/adhoc/graph_interface.h new file mode 100644 index 000000000000..a9cf938dcc36 --- /dev/null +++ b/flex/engines/graph_db/runtime/adhoc/graph_interface.h @@ -0,0 +1,572 @@ +/** Copyright 2020 Alibaba Group Holding Limited. + * + * 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. + */ + +#ifndef RUNTIME_ADHOC_GRAPH_INTERFACE_H_ +#define RUNTIME_ADHOC_GRAPH_INTERFACE_H_ + +#include +#include "flex/engines/graph_db/database/read_transaction.h" +#include "flex/engines/graph_db/runtime/common/rt_any.h" +#include "flex/utils/property/types.h" + +namespace gs { + +namespace runtime { + +namespace impl { + +/* + The following classes are used to provide a unified interface for adhoc + queries to access graph data. If you want to use your own Graph implementation + to run adhoc queries, you should specialize the following classes with your + own graph implementation. +*/ + +template +class PropertyGetter { + public: + using vertex_index_t = typename GRAPH_IMPL::vertex_index_t; + + PropertyGetter(); + + T operator[](vertex_index_t idx) const; + + bool EmptyProperty() const; + + T get_view(vertex_index_t idx) const; + + Any get_any(vertex_index_t idx) const; +}; + +/** + * Note: The generic class is not implemented, you should specialize it with + * your own graph implementation. + */ +template +class EdgeIterator { + public: + using vertex_index_t = typename GRAPH_IMPL::vertex_index_t; + + EdgeIterator(); + ~EdgeIterator(); + + Any GetData() const; + + bool IsValid() const; + + void Next(); + + vertex_index_t GetNeighbor() const; + + label_t GetNeighborLabel() const; + + label_t GetEdgeLabel() const; +}; + +/** + * Note: The generic class is not implemented, you should specialize it with + * your own graph implementation. + */ +template +class AdjList { + public: + using self_t = AdjList; + using vertex_index_t = typename GRAPH_IMPL::vertex_index_t; + class NbrIterator { + public: + using self_t = NbrIterator; + + const T& GetData() const; + vertex_index_t GetNeighbor() const; + const self_t& operator*() const; + const self_t* operator->() const; + NbrIterator& operator++(); + bool operator==(const NbrIterator& rhs) const; + bool operator!=(const NbrIterator& rhs) const; + }; + using edata_t = T; + using iterator = NbrIterator; + + AdjList(); + + inline iterator begin() const; + inline iterator end() const; +}; + +/** + * Note: The generic class is not implemented, you should specialize it with + * your own graph implementation. + */ +template +class SubGraph { + public: + using label_id_t = uint8_t; + using vertex_index_t = typename GRAPH_IMPL::vertex_index_t; + using edata_t = T; + + SubGraph(); + + AdjList GetEdges(vertex_index_t vid) const; +}; + +//////// Specialization for ReadTransaction //////// +template +class PropertyGetter { + public: + using vertex_index_t = typename ReadTransaction::vertex_index_t; + PropertyGetter() : column_(nullptr) {} + PropertyGetter(const TypedColumn* col) { column_ = col; } + + PropertyGetter(const ColumnBase* col) { + column_ = dynamic_cast*>(col); + } + + T operator[](vertex_index_t idx) const { + if (column_ == nullptr) { + return T(); + } + return column_->get_view(idx); + } + + bool EmptyProperty() const { return column_ == nullptr; } + + T get_view(vertex_index_t idx) const { + if (column_ == nullptr) { + return T(); + } + return column_->get_view(idx); + } + + RTAny get_any(vertex_index_t idx) const { + if (column_ == nullptr) { + return RTAny(RTAnyType::kNull); + } + return TypedConverter::from_typed(column_->get_view(idx)); + } + + private: + const TypedColumn* column_; +}; + +template <> +class EdgeIterator { + public: + using vertex_index_t = typename ReadTransaction::vertex_index_t; + using inner_iter_t = typename ReadTransaction::edge_iterator; + + EdgeIterator(inner_iter_t&& iter) : iter_(std::move(iter)) {} + ~EdgeIterator() {} + + inline Any GetData() const { return iter_.GetData(); } + + inline bool IsValid() const { return iter_.IsValid(); } + + inline void Next() { iter_.Next(); } + + inline vertex_index_t GetNeighbor() const { return iter_.GetNeighbor(); } + + inline label_t GetNeighborLabel() const { return iter_.GetNeighborLabel(); } + + inline label_t GetEdgeLabel() const { return iter_.GetEdgeLabel(); } + + private: + inner_iter_t iter_; +}; + +template +class AdjList { + public: + using self_t = AdjList; + using vertex_index_t = typename ReadTransaction::vertex_index_t; + class NbrIterator { + public: + using inner_iterator = typename AdjListView::nbr_iterator; + using self_t = NbrIterator; + NbrIterator(inner_iterator&& iter) : iter_(std::move(iter)) {} + + const T& GetData() const { return iter_->get_data(); } + + vertex_index_t GetNeighbor() const { return iter_->get_neighbor(); } + + const self_t& operator*() const { return *this; } + + const self_t* operator->() const { return this; } + + NbrIterator& operator++() { + ++iter_; + return *this; + } + + bool operator==(const NbrIterator& rhs) const { return iter_ == rhs.iter_; } + + bool operator!=(const NbrIterator& rhs) const { return iter_ != rhs.iter_; } + + private: + inner_iterator iter_; + }; + using edata_t = T; + using iterator = NbrIterator; + using inner_adj_list_t = AdjListView; + + AdjList(inner_adj_list_t&& adj_list) : adj_list_(std::move(adj_list)) {} + + inline iterator begin() const { return iterator(adj_list_.begin()); } + inline iterator end() const { return iterator(adj_list_.end()); } + + private: + inner_adj_list_t adj_list_; +}; + +template +class SubGraph { + public: + using label_id_t = uint8_t; + using vertex_index_t = typename ReadTransaction::vertex_index_t; + using edata_t = T; + using inner_graph_view = GraphView; + + SubGraph(inner_graph_view&& view) : view_(std::move(view)) {} + + AdjList GetEdges(vertex_index_t vid) const { + return AdjList(view_.get_edges(vid)); + } + + private: + inner_graph_view view_; +}; + +} // namespace impl + +/* + * The GraphInterface class provides a unified interface for adhoc queries to + * access graph data. The interface is designed to be generic and can be + * specialized with different graph implementations. The interface provides + * functions to access vertex and edge properties, get neighbors of a vertex, + * and get subgraphs. + * + * Note that the functions in these classes are not implemented, you should + * implement them by yourself. For example, if you want to use a graph with + * name `MyGraph`, you specialize the GraphInterface class like this: + * + * ```c++ + * class MyGraph { + * // Implement the graph interface functions + * }; + * + * template <> + * class GraphInterface { + * + * label_id_t VertexLabelNum() { ... } + * label_id_t EdgeLabelNum() const { ...} + * std::vector GetVertexLabels() const {...} + * + * // Other functions ... + * }; + * + * ``` + */ +template +class GraphInterface { + public: + using label_id_t = label_t; + using vertex_index_t = typename GRAPH_IMPL::vertex_index_t; + using edge_iterator_t = impl::EdgeIterator; + + template + using sub_graph_t = impl::SubGraph; + + label_id_t VertexLabelNum(); + label_id_t EdgeLabelNum() const; + std::vector GetVertexLabels() const; + std::vector GetEdgeLabels() const; + label_id_t GetVertexLabelId(const std::string& label) const; + label_id_t GetEdgeLabelId(const std::string& label) const; + std::string GetVertexLabelName(label_id_t label_id) const; + std::string GetEdgeLabelName(label_id_t label_id) const; + std::vector> + GetVertexPrimaryKeys(label_id_t label) const; + bool ExistVertexLabel(const std::string& label) const; + bool ExistVertexLabel(label_id_t label) const; + bool ExistEdgeLabel(const std::string& label) const; + bool ExistEdgeLabel(label_id_t label) const; + size_t VertexNum() const; + size_t VertexNum(label_id_t label) const; + size_t EdgeNum() const; + size_t EdgeNum(const label_id_t& src_label_id, const label_id_t& dst_label_id, + const label_id_t& edge_label_id) const; + + bool ExistEdgeTriplet(const label_id_t& src_label_id, + const label_id_t& dst_label_id, + const label_id_t& edge_label_id) const; + + const std::vector>& GetEdgeProperties( + const label_id_t& src_label_id, const label_id_t& dst_label_id, + const label_id_t& edge_label_id) const; + + const std::vector& GetEdgePropertyTypes( + const label_id_t& src_label_id, const label_id_t& dst_label_id, + const label_id_t& edge_label_id) const; + + const std::vector>& GetVertexProperties( + label_id_t label) const; + + /////////////////////////GRAPH DATA///////////////////////// + bool GetVertexIndex(label_id_t label, const Any& id, + vertex_index_t& index) const; + + RTAny GetVertexId(label_id_t label, vertex_index_t index) const; + + template + impl::PropertyGetter GetVertexPropertyGetter( + const label_id_t& label_id, const std::string& prop_name) const; + + Any GetVertexProperty(const label_id_t& label_id, + const std::string& prop_name, vertex_index_t vid) const; + + edge_iterator_t GetOutEdgeIterator(label_id_t src_label_id, + label_id_t nbr_label_id, + label_id_t edge_label_id, + vertex_index_t vid) const; + + // TODO(zhanglei):Change the order of the src_label, dst_label + edge_iterator_t GetInEdgeIterator(label_id_t dst_label_id, + label_id_t nbr_label_id, + label_id_t edge_label_id, + vertex_index_t vid) const; + + template + sub_graph_t GetOutgoingGraphView(label_id_t src_label_id, + label_id_t dst_label_id, + label_id_t edge_label_id) const; + + template + sub_graph_t GetIncomingGraphView(label_id_t src_label_id, + label_id_t dst_label_id, + label_id_t edge_label_id) const; +}; + +template <> +class GraphInterface { + public: + using label_id_t = label_t; + using vertex_index_t = typename ReadTransaction::vertex_index_t; + using edge_iterator_t = impl::EdgeIterator; + + template + using sub_graph_t = impl::SubGraph; + + GraphInterface(ReadTransaction& txn) : txn_(txn) {} + + label_id_t VertexLabelNum() const { return txn_.schema().vertex_label_num(); } + + label_id_t EdgeLabelNum() const { return txn_.schema().edge_label_num(); } + + std::vector GetVertexLabels() const { + std::vector labels; + for (label_id_t i = 0; i < VertexLabelNum(); ++i) { + labels.push_back(i); + } + return labels; + } + + std::vector GetEdgeLabels() const { + std::vector labels; + for (label_id_t i = 0; i < EdgeLabelNum(); ++i) { + labels.push_back(i); + } + return labels; + } + + label_id_t GetVertexLabelId(const std::string& label) const { + return txn_.schema().get_vertex_label_id(label); + } + + label_id_t GetEdgeLabelId(const std::string& label) const { + return txn_.schema().get_edge_label_id(label); + } + + std::string GetVertexLabelName(label_id_t label_id) const { + return txn_.schema().get_vertex_label_name(label_id); + } + + std::string GetEdgeLabelName(label_id_t label_id) const { + return txn_.schema().get_edge_label_name(label_id); + } + + const std::vector>& + GetVertexPrimaryKeys(label_id_t label) const { + return txn_.schema().get_vertex_primary_key(label); + } + + bool ExistVertexLabel(const std::string& label) const { + return txn_.schema().contains_vertex_label(label); + } + + bool ExistEdgeLabel(const std::string& label) const { + return txn_.schema().contains_edge_label(label); + } + + bool ExistVertexLabel(label_id_t label) const { + return label < VertexLabelNum(); + } + + bool ExistEdgeLabel(label_id_t label) const { return label < EdgeLabelNum(); } + + size_t VertexNum() const { + size_t cnt = 0; + for (label_id_t i = 0; i < VertexLabelNum(); ++i) { + cnt += VertexNum(i); + } + return cnt; + } + + size_t VertexNum(label_id_t label) const { return txn_.GetVertexNum(label); } + + size_t EdgeNum() const { + size_t cnt = 0; + for (label_id_t src_label = 0; src_label < VertexLabelNum(); ++src_label) { + for (label_id_t dst_label = 0; dst_label < VertexLabelNum(); + ++dst_label) { + for (label_id_t edge_label = 0; edge_label < EdgeLabelNum(); + ++edge_label) { + cnt += EdgeNum(src_label, dst_label, edge_label); + } + } + } + return cnt; + } + + size_t EdgeNum(const label_id_t& src_label_id, const label_id_t& dst_label_id, + const label_id_t& edge_label_id) const { + if (!ExistEdgeTriplet(src_label_id, dst_label_id, edge_label_id)) { + return 0; + } + size_t res = 0; + auto oe_csr = + txn_.graph().get_oe_csr(src_label_id, dst_label_id, edge_label_id); + auto ie_csr = + txn_.graph().get_ie_csr(dst_label_id, src_label_id, edge_label_id); + if (oe_csr) { + res = oe_csr->edge_num(); + } else if (ie_csr) { + res = ie_csr->edge_num(); + } + return res; + } + + bool ExistEdgeTriplet(const label_id_t& src_label_id, + const label_id_t& dst_label_id, + const label_id_t& edge_label_id) const { + return txn_.schema().exist(src_label_id, dst_label_id, edge_label_id); + } + std::vector GetEdgePropertyNames( + const label_id_t& src_label_id, const label_id_t& dst_label_id, + const label_id_t& edge_label_id) const { + if (!ExistEdgeTriplet(src_label_id, dst_label_id, edge_label_id)) { + return {}; + } + return txn_.schema().get_edge_property_names(src_label_id, dst_label_id, + edge_label_id); + } + + std::vector GetEdgePropertyTypes( + const label_id_t& src_label_id, const label_id_t& dst_label_id, + const label_id_t& edge_label_id) const { + if (!ExistEdgeTriplet(src_label_id, dst_label_id, edge_label_id)) { + return {}; + } + return txn_.schema().get_edge_properties(src_label_id, dst_label_id, + edge_label_id); + } + + std::vector GetVertexPropertyNames(label_id_t label) const { + return txn_.schema().get_vertex_property_names(label); + } + + std::vector GetVertexPropertyTypes(label_id_t label) const { + return txn_.schema().get_vertex_properties(label); + } + + /////////////////////////GRAPH DATA///////////////////////// + bool GetVertexIndex(label_id_t label, const Any& id, + vertex_index_t& index) const { + return txn_.GetVertexIndex(label, id, index); + } + + Any GetVertexId(label_id_t label, vertex_index_t index) const { + return txn_.GetVertexId(label, index); + } + + template + impl::PropertyGetter GetVertexPropertyGetter( + const label_id_t& label_id, const std::string& prop_name) const { + return impl::PropertyGetter( + txn_.get_vertex_property_column(label_id, prop_name).get()); + } + + Any GetVertexProperty(const label_id_t& label_id, const size_t prop_index, + vertex_index_t vid) const { + auto vertex_iter = txn_.GetVertexIterator(label_id); + vertex_iter.Goto(vid); + if (!vertex_iter.IsValid() || + vertex_iter.FieldNum() <= (int32_t) prop_index) { + LOG(ERROR) << "Invalid vertex or property index: " << vid << " " + << prop_index; + return Any(); + } + return vertex_iter.GetField(prop_index); + } + + edge_iterator_t GetOutEdgeIterator(label_id_t src_label_id, + label_id_t nbr_label_id, + label_id_t edge_label_id, + vertex_index_t vid) const { + return edge_iterator_t(txn_.GetOutEdgeIterator( + src_label_id, vid, nbr_label_id, edge_label_id)); + } + + edge_iterator_t GetInEdgeIterator(label_id_t dst_label_id, + label_id_t nbr_label_id, + label_id_t edge_label_id, + vertex_index_t vid) const { + return edge_iterator_t( + txn_.GetInEdgeIterator(dst_label_id, vid, nbr_label_id, edge_label_id)); + } + + template + sub_graph_t GetOutgoingGraphView(label_id_t src_label_id, + label_id_t dst_label_id, + label_id_t edge_label_id) const { + return sub_graph_t(txn_.GetOutgoingGraphView( + src_label_id, dst_label_id, edge_label_id)); + } + + template + sub_graph_t GetIncomingGraphView(label_id_t src_label_id, + label_id_t dst_label_id, + label_id_t edge_label_id) const { + return sub_graph_t(txn_.GetIncomingGraphView( + src_label_id, dst_label_id, edge_label_id)); + } + + private: + ReadTransaction& txn_; +}; + +} // namespace runtime + +} // namespace gs + +#endif // RUNTIME_ADHOC_GRAPH_INTERFACE_H_ \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/adhoc/operators/dedup.cc b/flex/engines/graph_db/runtime/adhoc/operators/dedup.h similarity index 87% rename from flex/engines/graph_db/runtime/adhoc/operators/dedup.cc rename to flex/engines/graph_db/runtime/adhoc/operators/dedup.h index 0e5470b8fce4..bf711bfd4e0e 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/dedup.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/dedup.h @@ -13,16 +13,17 @@ * limitations under the License. */ -#include "flex/engines/graph_db/runtime/common/operators/dedup.h" -#include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" #include "flex/engines/graph_db/runtime/adhoc/var.h" +#include "flex/engines/graph_db/runtime/common/operators/dedup.h" namespace gs { namespace runtime { +template bl::result eval_dedup(const algebra::Dedup& opr, - const ReadTransaction& txn, Context&& ctx) { + const GraphInterface& txn, + Context&& ctx) { std::vector keys; std::vector> vars; int keys_num = opr.keys_size(); @@ -35,7 +36,7 @@ bl::result eval_dedup(const algebra::Dedup& opr, tag = key.tag().id(); } if (key.has_property()) { - Var var(txn, ctx, key, VarType::kPathVar); + Var var(txn, ctx, key, VarType::kPathVar); vars.emplace_back([var](size_t i) { return var.get(i); }); flag = true; } else { diff --git a/flex/engines/graph_db/runtime/adhoc/operators/edge_expand.cc b/flex/engines/graph_db/runtime/adhoc/operators/edge_expand.h similarity index 93% rename from flex/engines/graph_db/runtime/adhoc/operators/edge_expand.cc rename to flex/engines/graph_db/runtime/adhoc/operators/edge_expand.h index c0e75d69cd40..8797c4a43f26 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/edge_expand.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/edge_expand.h @@ -13,19 +13,19 @@ * limitations under the License. */ -#include "flex/engines/graph_db/runtime/common/operators/edge_expand.h" -#include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" #include "flex/engines/graph_db/runtime/adhoc/predicates.h" #include "flex/engines/graph_db/runtime/adhoc/utils.h" #include "flex/engines/graph_db/runtime/common/context.h" +#include "flex/engines/graph_db/runtime/common/operators/edge_expand.h" namespace gs { namespace runtime { +template bl::result eval_edge_expand( - const physical::EdgeExpand& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params, + const physical::EdgeExpand& opr, const GraphInterface& txn, + Context&& ctx, const std::map& params, const physical::PhysicalOpr_MetaData& meta) { int v_tag; if (!opr.has_v_tag()) { diff --git a/flex/engines/graph_db/runtime/adhoc/operators/get_v.cc b/flex/engines/graph_db/runtime/adhoc/operators/get_v.h similarity index 94% rename from flex/engines/graph_db/runtime/adhoc/operators/get_v.cc rename to flex/engines/graph_db/runtime/adhoc/operators/get_v.h index c1e18a10fc6a..dbafe9feb0fa 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/get_v.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/get_v.h @@ -13,10 +13,10 @@ * limitations under the License. */ -#include "flex/engines/graph_db/runtime/common/operators/get_v.h" #include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" #include "flex/engines/graph_db/runtime/adhoc/predicates.h" #include "flex/engines/graph_db/runtime/adhoc/utils.h" +#include "flex/engines/graph_db/runtime/common/operators/get_v.h" namespace gs { @@ -39,9 +39,10 @@ VOpt parse_opt(const physical::GetV_VOpt& opt) { } } +template bl::result eval_get_v( - const physical::GetV& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params) { + const physical::GetV& opr, const GraphInterface& txn, + Context&& ctx, const std::map& params) { int tag = -1; if (opr.has_tag()) { tag = opr.tag().value(); diff --git a/flex/engines/graph_db/runtime/adhoc/operators/group_by.cc b/flex/engines/graph_db/runtime/adhoc/operators/group_by.h similarity index 86% rename from flex/engines/graph_db/runtime/adhoc/operators/group_by.cc rename to flex/engines/graph_db/runtime/adhoc/operators/group_by.h index 14f070759c1e..6bdb0c8e3e93 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/group_by.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/group_by.h @@ -61,9 +61,10 @@ AggrKind parse_aggregate(physical::GroupBy_AggFunc::Aggregate v) { } } +template struct AggFunc { - AggFunc(const physical::GroupBy_AggFunc& opr, const ReadTransaction& txn, - const Context& ctx) + AggFunc(const physical::GroupBy_AggFunc& opr, + const GraphInterface& txn, const Context& ctx) : aggregate(parse_aggregate(opr.aggregate())), alias(-1) { if (opr.has_alias()) { alias = opr.alias().value(); @@ -74,28 +75,30 @@ struct AggFunc { } } - std::vector vars; + std::vector> vars; AggrKind aggregate; int alias; }; +template struct AggKey { - AggKey(const physical::GroupBy_KeyAlias& opr, const ReadTransaction& txn, - const Context& ctx) + AggKey(const physical::GroupBy_KeyAlias& opr, + const GraphInterface& txn, const Context& ctx) : key(txn, ctx, opr.key(), VarType::kPathVar), alias(-1) { if (opr.has_alias()) { alias = opr.alias().value(); } } - Var key; + Var key; int alias; std::shared_ptr column_builder; }; +template std::pair>, Context> generate_aggregate_indices( - const std::vector& keys, size_t row_num, - const std::vector& functions) { + const std::vector>& keys, size_t row_num, + const std::vector>& functions) { std::unordered_map sig_to_root; std::vector> root_list; std::vector> ret; @@ -168,9 +171,10 @@ std::pair>, Context> generate_aggregate_indices( return std::make_pair(std::move(ret), std::move(ret_ctx)); } -template +template std::shared_ptr numeric_sum( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ValueColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -185,9 +189,10 @@ std::shared_ptr numeric_sum( return builder.finish(); } -template +template std::shared_ptr numeric_count_distinct( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ValueColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -202,8 +207,10 @@ std::shared_ptr numeric_count_distinct( return builder.finish(); } +template std::shared_ptr vertex_count_distinct( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ValueColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -218,8 +225,9 @@ std::shared_ptr vertex_count_distinct( return builder.finish(); } +template std::shared_ptr general_count_distinct( - const std::vector& vars, + const std::vector>& vars, const std::vector>& to_aggregate) { ValueColumnBuilder builder; size_t col_size = to_aggregate.size(); @@ -243,8 +251,9 @@ std::shared_ptr general_count_distinct( return builder.finish(); } +template std::shared_ptr general_count( - const std::vector& vars, + const std::vector>& vars, const std::vector>& to_aggregate) { ValueColumnBuilder builder; if (vars.size() == 1) { @@ -274,8 +283,10 @@ std::shared_ptr general_count( return builder.finish(); } +template std::shared_ptr vertex_first( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { MLVertexColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -289,9 +300,10 @@ std::shared_ptr vertex_first( return builder.finish(); } -template +template std::shared_ptr general_first( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ValueColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -305,9 +317,10 @@ std::shared_ptr general_first( return builder.finish(); } -template +template std::shared_ptr general_min( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ValueColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -329,9 +342,10 @@ std::shared_ptr general_min( return builder.finish(); } -template +template std::shared_ptr general_max( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ValueColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -353,8 +367,10 @@ std::shared_ptr general_max( return builder.finish(); } +template std::shared_ptr string_to_set( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ValueColumnBuilder> builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -369,8 +385,10 @@ std::shared_ptr string_to_set( return builder.finish(); } +template std::shared_ptr tuple_to_list( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ListValueColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -391,8 +409,10 @@ std::shared_ptr tuple_to_list( return builder.finish(); } +template std::shared_ptr string_to_list( - const Var& var, const std::vector>& to_aggregate) { + const Var& var, + const std::vector>& to_aggregate) { ListValueColumnBuilder builder; size_t col_size = to_aggregate.size(); builder.reserve(col_size); @@ -413,13 +433,15 @@ std::shared_ptr string_to_list( return builder.finish(); } +template bl::result> apply_reduce( - const AggFunc& func, const std::vector>& to_aggregate) { + const AggFunc& func, + const std::vector>& to_aggregate) { if (func.aggregate == AggrKind::kSum) { if (func.vars.size() != 1) { LOG(FATAL) << "only 1 variable to sum is allowed"; } - const Var& var = func.vars[0]; + const auto& var = func.vars[0]; if (var.type() == RTAnyType::kI32Value) { return numeric_sum(var, to_aggregate); } else { @@ -434,7 +456,7 @@ bl::result> apply_reduce( if (func.vars.size() != 1) { LOG(FATAL) << "only 1 variable to to_set is allowed"; } - const Var& var = func.vars[0]; + const auto& var = func.vars[0]; if (var.type() == RTAnyType::kStringValue) { return string_to_set(var, to_aggregate); } else { @@ -447,7 +469,7 @@ bl::result> apply_reduce( } } else if (func.aggregate == AggrKind::kCountDistinct) { if (func.vars.size() == 1 && func.vars[0].type() == RTAnyType::kVertex) { - const Var& var = func.vars[0]; + const auto& var = func.vars[0]; return vertex_count_distinct(var, to_aggregate); } else { return general_count_distinct(func.vars, to_aggregate); @@ -460,7 +482,7 @@ bl::result> apply_reduce( LOG(FATAL) << "only 1 variable to first is allowed"; } - const Var& var = func.vars[0]; + const auto& var = func.vars[0]; if (var.type() == RTAnyType::kVertex) { return vertex_first(var, to_aggregate); } else if (var.type() == RTAnyType::kI64Value) { @@ -471,7 +493,7 @@ bl::result> apply_reduce( LOG(FATAL) << "only 1 variable to min is allowed"; } - const Var& var = func.vars[0]; + const auto& var = func.vars[0]; if (var.type() == RTAnyType::kI32Value) { return general_min(var, to_aggregate); } else if (var.type() == RTAnyType::kStringValue) { @@ -482,14 +504,14 @@ bl::result> apply_reduce( LOG(FATAL) << "only 1 variable to max is allowed"; } - const Var& var = func.vars[0]; + const auto& var = func.vars[0]; if (var.type() == RTAnyType::kI32Value) { return general_max(var, to_aggregate); } else if (var.type() == RTAnyType::kStringValue) { return general_max(var, to_aggregate); } } else if (func.aggregate == AggrKind::kToList) { - const Var& var = func.vars[0]; + const auto& var = func.vars[0]; if (func.vars.size() != 1) { LOG(FATAL) << "only 1 variable to to_list is allowed"; } @@ -505,7 +527,7 @@ bl::result> apply_reduce( LOG(FATAL) << "only 1 variable to avg is allowed"; } // LOG(FATAL) << "not support"; - const Var& var = func.vars[0]; + const auto& var = func.vars[0]; if (var.type() == RTAnyType::kI32Value) { ValueColumnBuilder builder; size_t col_size = to_aggregate.size(); @@ -530,10 +552,12 @@ bl::result> apply_reduce( return nullptr; } +template bl::result eval_group_by(const physical::GroupBy& opr, - const ReadTransaction& txn, Context&& ctx) { - std::vector functions; - std::vector mappings; + const GraphInterface& txn, + Context&& ctx) { + std::vector> functions; + std::vector> mappings; int func_num = opr.functions_size(); for (int i = 0; i < func_num; ++i) { functions.emplace_back(opr.functions(i), txn, ctx); diff --git a/flex/engines/graph_db/runtime/adhoc/operators/intersect.cc b/flex/engines/graph_db/runtime/adhoc/operators/intersect.h similarity index 91% rename from flex/engines/graph_db/runtime/adhoc/operators/intersect.cc rename to flex/engines/graph_db/runtime/adhoc/operators/intersect.h index 0129b2040505..15c8698045d5 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/intersect.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/intersect.h @@ -13,14 +13,15 @@ * limitations under the License. */ -#include "flex/engines/graph_db/runtime/common/operators/intersect.h" #include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" #include "flex/engines/graph_db/runtime/common/columns/edge_columns.h" +#include "flex/engines/graph_db/runtime/common/operators/intersect.h" namespace gs { namespace runtime { -bl::result eval_intersect(const ReadTransaction& txn, +template +bl::result eval_intersect(const GraphInterface& txn, const physical::Intersect& opr, std::vector&& ctxs) { int32_t key = opr.key(); diff --git a/flex/engines/graph_db/runtime/adhoc/operators/join.cc b/flex/engines/graph_db/runtime/adhoc/operators/join.h similarity index 99% rename from flex/engines/graph_db/runtime/adhoc/operators/join.cc rename to flex/engines/graph_db/runtime/adhoc/operators/join.h index 613451173562..0a54e09f89f0 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/join.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/join.h @@ -13,11 +13,12 @@ * limitations under the License. */ -#include "flex/engines/graph_db/runtime/common/operators/join.h" #include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" +#include "flex/engines/graph_db/runtime/common/operators/join.h" namespace gs { namespace runtime { + bl::result eval_join(const physical::Join& opr, Context&& ctx, Context&& ctx2) { JoinParams p; diff --git a/flex/engines/graph_db/runtime/adhoc/operators/limit.cc b/flex/engines/graph_db/runtime/adhoc/operators/limit.h similarity index 100% rename from flex/engines/graph_db/runtime/adhoc/operators/limit.cc rename to flex/engines/graph_db/runtime/adhoc/operators/limit.h diff --git a/flex/engines/graph_db/runtime/adhoc/operators/operators.h b/flex/engines/graph_db/runtime/adhoc/operators/operators.h index 395d94acae9c..ff4b6ac88743 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/operators.h +++ b/flex/engines/graph_db/runtime/adhoc/operators/operators.h @@ -16,71 +16,31 @@ #ifndef RUNTIME_ADHOC_OPERATORS_OPERATORS_H_ #define RUNTIME_ADHOC_OPERATORS_OPERATORS_H_ +#include "flex/engines/graph_db/runtime/common/leaf_utils.h" #include "flex/proto_generated_gie/algebra.pb.h" #include "flex/proto_generated_gie/physical.pb.h" #include "flex/engines/graph_db/database/read_transaction.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/dedup.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/edge_expand.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/get_v.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/group_by.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/intersect.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/join.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/limit.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/order_by.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/path_expand.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/project.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/scan.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/select.h" +#include "flex/engines/graph_db/runtime/adhoc/operators/sink.h" #include "flex/engines/graph_db/runtime/common/context.h" -#include "flex/engines/graph_db/runtime/common/leaf_utils.h" + #include "flex/utils/app_utils.h" namespace gs { -namespace runtime { - -bl::result eval_dedup(const algebra::Dedup& opr, - const ReadTransaction& txn, Context&& ctx); - -bl::result eval_group_by(const physical::GroupBy& opr, - const ReadTransaction& txn, Context&& ctx); - -bl::result eval_order_by(const algebra::OrderBy& opr, - const ReadTransaction& txn, Context&& ctx); - -bl::result eval_path_expand_v( - const physical::PathExpand& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params, - const physical::PhysicalOpr_MetaData& meta, int alias); - -bl::result eval_path_expand_p( - const physical::PathExpand& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params, - const physical::PhysicalOpr_MetaData& meta, int alias); - -bl::result eval_project( - const physical::Project& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params, - const std::vector& data_types); - -bl::result eval_scan(const physical::Scan& scan_opr, - const ReadTransaction& txn, - const std::map& params); - -bl::result eval_select( - const algebra::Select& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params); - -bl::result eval_edge_expand( - const physical::EdgeExpand& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params, - const physical::PhysicalOpr_MetaData& meta); - -bl::result eval_get_v( - const physical::GetV& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params); - -bl::result eval_intersect(const ReadTransaction& txn, - const physical::Intersect& opr, - std::vector&& ctx); - -bl::result eval_join(const physical::Join& opr, Context&& ctx, - Context&& ctx2); - -bl::result eval_limit(const algebra::Limit& opr, Context&& ctx); - -void eval_sink(const Context& ctx, const ReadTransaction& txn, Encoder& output); - -} // namespace runtime +namespace runtime {} // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/adhoc/operators/order_by.cc b/flex/engines/graph_db/runtime/adhoc/operators/order_by.h similarity index 81% rename from flex/engines/graph_db/runtime/adhoc/operators/order_by.cc rename to flex/engines/graph_db/runtime/adhoc/operators/order_by.h index 2e85ef0607f1..d19703e7134c 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/order_by.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/order_by.h @@ -24,12 +24,13 @@ namespace gs { namespace runtime { +template class GeneralComparer { public: GeneralComparer() : keys_num_(0) {} ~GeneralComparer() {} - void add_keys(Var&& key, bool asc) { + void add_keys(Var&& key, bool asc) { keys_.emplace_back(std::move(key)); order_.push_back(asc); ++keys_num_; @@ -52,13 +53,15 @@ class GeneralComparer { } private: - std::vector keys_; + std::vector> keys_; std::vector order_; size_t keys_num_; }; +template bl::result eval_order_by(const algebra::OrderBy& opr, - const ReadTransaction& txn, Context&& ctx) { + const GraphInterface& txn, + Context&& ctx) { int lower = 0; int upper = std::numeric_limits::max(); if (opr.has_limit()) { @@ -66,11 +69,11 @@ bl::result eval_order_by(const algebra::OrderBy& opr, upper = std::min(upper, static_cast(opr.limit().upper())); } - GeneralComparer cmp; + GeneralComparer cmp; int keys_num = opr.pairs_size(); for (int i = 0; i < keys_num; ++i) { const algebra::OrderBy_OrderingPair& pair = opr.pairs(i); - Var v(txn, ctx, pair.key(), VarType::kPathVar); + Var v(txn, ctx, pair.key(), VarType::kPathVar); CHECK(pair.order() == algebra::OrderBy_OrderingPair_Order:: OrderBy_OrderingPair_Order_ASC || pair.order() == algebra::OrderBy_OrderingPair_Order:: @@ -81,7 +84,8 @@ bl::result eval_order_by(const algebra::OrderBy& opr, cmp.add_keys(std::move(v), order); } - OrderBy::order_by_with_limit(txn, ctx, cmp, lower, upper); + OrderBy::order_by_with_limit>(ctx, cmp, lower, + upper); return ctx; } diff --git a/flex/engines/graph_db/runtime/adhoc/operators/path_expand.cc b/flex/engines/graph_db/runtime/adhoc/operators/path_expand.h similarity index 91% rename from flex/engines/graph_db/runtime/adhoc/operators/path_expand.cc rename to flex/engines/graph_db/runtime/adhoc/operators/path_expand.h index 5b2ba7e244cf..80a6876e721c 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/path_expand.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/path_expand.h @@ -13,17 +13,18 @@ * limitations under the License. */ -#include "flex/engines/graph_db/runtime/common/operators/path_expand.h" #include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" #include "flex/engines/graph_db/runtime/adhoc/utils.h" +#include "flex/engines/graph_db/runtime/common/operators/path_expand.h" namespace gs { namespace runtime { +template bl::result eval_path_expand_v( - const physical::PathExpand& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params, + const physical::PathExpand& opr, const GraphInterface& txn, + Context&& ctx, const std::map& params, const physical::PhysicalOpr_MetaData& meta, int alias) { CHECK(opr.has_start_tag()); int start_tag = opr.start_tag().value(); @@ -67,9 +68,10 @@ bl::result eval_path_expand_v( return ctx; } +template bl::result eval_path_expand_p( - const physical::PathExpand& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params, + const physical::PathExpand& opr, const GraphInterface& txn, + Context&& ctx, const std::map& params, const physical::PhysicalOpr_MetaData& meta, int alias) { CHECK(opr.has_start_tag()); int start_tag = opr.start_tag().value(); diff --git a/flex/engines/graph_db/runtime/adhoc/operators/project.cc b/flex/engines/graph_db/runtime/adhoc/operators/project.h similarity index 89% rename from flex/engines/graph_db/runtime/adhoc/operators/project.cc rename to flex/engines/graph_db/runtime/adhoc/operators/project.h index 3c372aef709c..b610b4305fd9 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/project.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/project.h @@ -42,9 +42,10 @@ bool exchange_tag_alias(const physical::Project_ExprAlias& m, int& tag, return false; } +template bl::result eval_project( - const physical::Project& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params, + const physical::Project& opr, const GraphInterface& txn, + Context&& ctx, const std::map& params, const std::vector& data_types) { bool is_append = opr.is_append(); Context ret; @@ -65,7 +66,7 @@ bl::result eval_project( continue; } } - Expr expr(txn, ctx, params, m.expr(), VarType::kPathVar); + Expr expr(txn, ctx, params, m.expr(), VarType::kPathVar); int alias = -1; if (m.has_alias()) { alias = m.alias().value(); @@ -86,7 +87,7 @@ bl::result eval_project( } } - Expr expr(txn, ctx, params, m.expr(), VarType::kPathVar); + Expr expr(txn, ctx, params, m.expr(), VarType::kPathVar); int alias = -1; if (m.has_alias()) { alias = m.alias().value(); diff --git a/flex/engines/graph_db/runtime/adhoc/operators/scan.cc b/flex/engines/graph_db/runtime/adhoc/operators/scan.h similarity index 96% rename from flex/engines/graph_db/runtime/adhoc/operators/scan.cc rename to flex/engines/graph_db/runtime/adhoc/operators/scan.h index d9cff3bfa4de..04e356166bd6 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/scan.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/scan.h @@ -13,9 +13,9 @@ * limitations under the License. */ -#include "flex/engines/graph_db/runtime/common/operators/scan.h" #include "flex/engines/graph_db/runtime/adhoc/expr_impl.h" #include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" +#include "flex/engines/graph_db/runtime/common/operators/scan.h" namespace gs { namespace runtime { @@ -98,9 +98,10 @@ static bool is_find_vertex(const physical::Scan& scan_opr, return true; } +template static bl::result scan_vertices_expr_impl( bool scan_oid, const std::vector& input_ids, - const ReadTransaction& txn, const ScanParams& scan_params, + const GraphInterface& txn, const ScanParams& scan_params, std::unique_ptr expr) { if (scan_oid) { return Scan::filter_oids( @@ -126,9 +127,10 @@ static bl::result scan_vertices_expr_impl( } } +template static bl::result scan_vertices_no_expr_impl( bool scan_oid, const std::vector& input_ids, - const ReadTransaction& txn, const ScanParams& scan_params) { + const GraphInterface& txn, const ScanParams& scan_params) { if (scan_oid) { return Scan::filter_oids( txn, scan_params, [](label_t label, vid_t vid) { return true; }, @@ -225,8 +227,9 @@ bool parse_idx_predicate(const algebra::IndexPredicate& predicate, return true; } +template bl::result eval_scan( - const physical::Scan& scan_opr, const ReadTransaction& txn, + const physical::Scan& scan_opr, const GraphInterface& txn, const std::map& params) { label_t label; int64_t vertex_id; @@ -250,17 +253,16 @@ bl::result eval_scan( const auto& scan_opr_params = scan_opr.params(); for (const auto& table : scan_opr_params.tables()) { // exclude invalid vertex label id - if (txn.schema().vertex_label_num() <= table.id()) { + if (!txn.ExistVertexLabel(table.id())) { continue; } scan_params.tables.push_back(table.id()); - const auto& pks = txn.schema().get_vertex_primary_key(table.id()); + auto pks = txn.GetVertexPrimaryKeys(table.id()); if (pks.size() > 1) { LOG(ERROR) << "only support one primary key"; RETURN_UNSUPPORTED_ERROR("only support one primary key"); } - auto [type, _, __] = pks[0]; - if (type != PropertyType::kInt64) { + if (std::get<0>(pks[0]) != PropertyType::kInt64) { has_other_type_oid = true; } } diff --git a/flex/engines/graph_db/runtime/adhoc/operators/select.cc b/flex/engines/graph_db/runtime/adhoc/operators/select.h similarity index 84% rename from flex/engines/graph_db/runtime/adhoc/operators/select.cc rename to flex/engines/graph_db/runtime/adhoc/operators/select.h index 0d786c224789..b632f1ac30b1 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/select.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/select.h @@ -20,10 +20,11 @@ namespace gs { namespace runtime { +template bl::result eval_select( - const algebra::Select& opr, const ReadTransaction& txn, Context&& ctx, - const std::map& params) { - Expr expr(txn, ctx, params, opr.predicate(), VarType::kPathVar); + const algebra::Select& opr, const GraphInterface& txn, + Context&& ctx, const std::map& params) { + Expr expr(txn, ctx, params, opr.predicate(), VarType::kPathVar); std::vector offsets; size_t row_num = ctx.row_num(); if (expr.is_optional()) { diff --git a/flex/engines/graph_db/runtime/adhoc/operators/sink.cc b/flex/engines/graph_db/runtime/adhoc/operators/sink.cc deleted file mode 100644 index 64d97c57cd00..000000000000 --- a/flex/engines/graph_db/runtime/adhoc/operators/sink.cc +++ /dev/null @@ -1,46 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" -#include "flex/proto_generated_gie/results.pb.h" - -namespace gs { - -namespace runtime { - -void eval_sink(const Context& ctx, const ReadTransaction& txn, - Encoder& output) { - size_t row_num = ctx.row_num(); - results::CollectiveResults results; - for (size_t i = 0; i < row_num; ++i) { - auto result = results.add_results(); - for (size_t j : ctx.tag_ids) { - auto col = ctx.get(j); - if (col == nullptr) { - continue; - } - auto column = result->mutable_record()->add_columns(); - auto val = col->get_elem(i); - val.sink(txn, j, column); - } - } - // LOG(INFO) << "sink: " << results.DebugString(); - auto res = results.SerializeAsString(); - output.put_bytes(res.data(), res.size()); -} - -} // namespace runtime - -} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/adhoc/operators/sink.h b/flex/engines/graph_db/runtime/adhoc/operators/sink.h new file mode 100644 index 000000000000..ac4487165615 --- /dev/null +++ b/flex/engines/graph_db/runtime/adhoc/operators/sink.h @@ -0,0 +1,196 @@ +/** Copyright 2020 Alibaba Group Holding Limited. + * + * 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. + */ + +#include "flex/engines/graph_db/runtime/adhoc/operators/operators.h" +#include "flex/proto_generated_gie/results.pb.h" + +namespace gs { + +namespace runtime { + +void sink_impl(const RTAny& any, common::Value* value) { + const auto& type_ = any.type_; + const auto& value_ = any.value_; + if (type_ == RTAnyType::kI64Value) { + value->set_i64(value_.i64_val); + } else if (type_ == RTAnyType::kStringValue) { + value->set_str(value_.str_val.data(), value_.str_val.size()); + } else if (type_ == RTAnyType::kI32Value) { + value->set_i32(value_.i32_val); + } else if (type_ == RTAnyType::kStringSetValue) { + LOG(FATAL) << "not support string set sink"; + } else if (type_ == RTAnyType::kDate32) { + value->set_i64(value_.i64_val); + } else if (type_ == RTAnyType::kBoolValue) { + value->set_boolean(value_.b_val); + } else if (type_ == RTAnyType::kF64Value) { + value->set_f64(value_.f64_val); + } else if (type_ == RTAnyType::kList) { + LOG(FATAL) << "not support list sink"; + } else if (type_ == RTAnyType::kTuple) { + auto tup = value_.t; + for (size_t i = 0; i < value_.t.size(); ++i) { + std::string s = tup.get(i).to_string(); + value->mutable_str_array()->add_item(s.data(), s.size()); + } + } else { + LOG(FATAL) << "not implemented for " << static_cast(type_.type_enum_); + } +} + +static void sink_any(const Any& any, common::Value* value) { + if (any.type == PropertyType::Int64()) { + value->set_i64(any.AsInt64()); + } else if (any.type == PropertyType::StringView()) { + auto str = any.AsStringView(); + value->set_str(str.data(), str.size()); + } else if (any.type == PropertyType::Date()) { + value->set_i64(any.AsDate().milli_second); + } else if (any.type == PropertyType::Int32()) { + value->set_i32(any.AsInt32()); + } else if (any.type == PropertyType::Double()) { + value->set_f64(any.AsDouble()); + } else if (any.type == PropertyType::Bool()) { + value->set_boolean(any.AsBool()); + } else if (any.type == PropertyType::Double()) { + value->set_f64(any.AsDouble()); + } else { + LOG(FATAL) << "Any value: " << any.to_string() + << ", type = " << any.type.type_enum; + } +} + +template +void sink_vertex(const GraphInterface& txn, + const std::pair& vertex, results::Vertex* v) { + v->mutable_label()->set_id(vertex.first); + v->set_id(encode_unique_vertex_id(vertex.first, vertex.second)); + const auto& vertex_prop_names = txn.GetVertexPropertyNames(vertex.first); + for (size_t i = 0; i < vertex_prop_names.size(); ++i) { + auto prop = v->add_properties(); + prop->mutable_key()->set_name(vertex_prop_names[i]); + sink_any(txn.GetVertexProperty(vertex.first, i, vertex.second), + prop->mutable_value()); + } +} + +template +void sink(const RTAny& any, const GraphInterface& txn, int id, + results::Column* col) { + const auto& type_ = any.type_; + const auto& value_ = any.value_; + col->mutable_name_or_id()->set_id(id); + if (type_ == RTAnyType::kList) { + auto collection = col->mutable_entry()->mutable_collection(); + for (size_t i = 0; i < value_.list.size(); ++i) { + sink_impl(value_.list.get(i), + collection->add_collection()->mutable_object()); + } + } else if (type_ == RTAnyType::kStringSetValue) { + auto collection = col->mutable_entry()->mutable_collection(); + for (auto& s : *value_.str_set) { + collection->add_collection()->mutable_object()->set_str(s); + } + } else if (type_ == RTAnyType::kTuple) { + auto collection = col->mutable_entry()->mutable_collection(); + for (size_t i = 0; i < value_.t.size(); ++i) { + sink_impl(value_.t.get(i), + collection->add_collection()->mutable_object()); + } + } else if (type_ == RTAnyType::kVertex) { + auto v = col->mutable_entry()->mutable_element()->mutable_vertex(); + sink_vertex(txn, value_.vertex, v); + + } else if (type_ == RTAnyType::kMap) { + auto mp = col->mutable_entry()->mutable_map(); + auto [keys_ptr, vals_ptr] = value_.map.key_vals(); + auto& keys = *keys_ptr; + auto& vals = *vals_ptr; + for (size_t i = 0; i < keys.size(); ++i) { + if (vals[i].is_null()) { + continue; + } + auto ret = mp->add_key_values(); + ret->mutable_key()->set_str(keys[i]); + if (vals[i].type_ == RTAnyType::kVertex) { + auto v = ret->mutable_value()->mutable_element()->mutable_vertex(); + sink_vertex(txn, vals[i].as_vertex(), v); + } else { + sink_impl(vals[i], + ret->mutable_value()->mutable_element()->mutable_object()); + } + } + + } else if (type_ == RTAnyType::kEdge) { + auto e = col->mutable_entry()->mutable_element()->mutable_edge(); + auto [label, src, dst, prop, dir] = any.as_edge(); + e->mutable_src_label()->set_id(label.src_label); + e->mutable_dst_label()->set_id(label.dst_label); + auto edge_label = generate_edge_label_id(label.src_label, label.dst_label, + label.edge_label); + e->mutable_label()->set_id(label.edge_label); + e->set_src_id(encode_unique_vertex_id(label.src_label, src)); + e->set_dst_id(encode_unique_vertex_id(label.dst_label, dst)); + e->set_id(encode_unique_edge_id(edge_label, src, dst)); + const auto& edge_props_names = txn.GetEdgePropertyNames( + label.src_label, label.dst_label, label.edge_label); + if (edge_props_names.size() == 1) { + auto props = e->add_properties(); + props->mutable_key()->set_name(edge_props_names[0]); + sink_any(prop, e->mutable_properties(0)->mutable_value()); + } else if (edge_props_names.size() > 1) { + auto rv = prop.AsRecordView(); + if (rv.size() != edge_props_names.size()) { + LOG(ERROR) << "record view size not match with prop names"; + } + for (size_t i = 0; i < edge_props_names.size(); ++i) { + auto props = e->add_properties(); + props->mutable_key()->set_name(edge_props_names[i]); + sink_any(rv[i], props->mutable_value()); + } + } + } else if (type_ == RTAnyType::kPath) { + LOG(FATAL) << "not support path sink"; + + } else { + sink_impl(any, col->mutable_entry()->mutable_element()->mutable_object()); + } +} + +template +void eval_sink(const Context& ctx, const GraphInterface& txn, + Encoder& output) { + size_t row_num = ctx.row_num(); + results::CollectiveResults results; + for (size_t i = 0; i < row_num; ++i) { + auto result = results.add_results(); + for (size_t j : ctx.tag_ids) { + auto col = ctx.get(j); + if (col == nullptr) { + continue; + } + auto column = result->mutable_record()->add_columns(); + auto val = col->get_elem(i); + sink(val, txn, j, column); + } + } + // LOG(INFO) << "sink: " << results.DebugString(); + auto res = results.SerializeAsString(); + output.put_bytes(res.data(), res.size()); +} + +} // namespace runtime + +} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/adhoc/predicates.h b/flex/engines/graph_db/runtime/adhoc/predicates.h index 560ffc9c40b7..296066288671 100644 --- a/flex/engines/graph_db/runtime/adhoc/predicates.h +++ b/flex/engines/graph_db/runtime/adhoc/predicates.h @@ -25,8 +25,10 @@ namespace gs { namespace runtime { +template struct GeneralPathPredicate { - GeneralPathPredicate(const ReadTransaction& txn, const Context& ctx, + GeneralPathPredicate(const GraphInterface& txn, + const Context& ctx, const std::map& params, const common::Expression& expr) : expr_(txn, ctx, params, expr, VarType::kPathVar) {} @@ -36,11 +38,13 @@ struct GeneralPathPredicate { return val.as_bool(); } - Expr expr_; + Expr expr_; }; +template struct GeneralVertexPredicate { - GeneralVertexPredicate(const ReadTransaction& txn, const Context& ctx, + GeneralVertexPredicate(const GraphInterface& txn, + const Context& ctx, const std::map& params, const common::Expression& expr) : expr_(txn, ctx, params, expr, VarType::kVertexVar) {} @@ -50,11 +54,12 @@ struct GeneralVertexPredicate { return val.as_bool(); } - Expr expr_; + Expr expr_; }; - +template struct GeneralEdgePredicate { - GeneralEdgePredicate(const ReadTransaction& txn, const Context& ctx, + GeneralEdgePredicate(const GraphInterface& txn, + const Context& ctx, const std::map& params, const common::Expression& expr) : expr_(txn, ctx, params, expr, VarType::kEdgeVar) {} @@ -65,7 +70,7 @@ struct GeneralEdgePredicate { return val.as_bool(); } - Expr expr_; + Expr expr_; }; struct DummyVertexPredicate { diff --git a/flex/engines/graph_db/runtime/adhoc/runtime.cc b/flex/engines/graph_db/runtime/adhoc/runtime.cc deleted file mode 100644 index 48f35b9b2992..000000000000 --- a/flex/engines/graph_db/runtime/adhoc/runtime.cc +++ /dev/null @@ -1,256 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/adhoc/runtime.h" - -#include "flex/engines/graph_db/runtime/common/leaf_utils.h" - -namespace gs { - -namespace runtime { - -class OpCost { - public: - OpCost() {} - ~OpCost() { - double total = 0; - for (auto& pair : table) { - total += pair.second; - } - LOG(INFO) << "op elapsed time: "; - for (auto& pair : table) { - LOG(INFO) << "\t" << pair.first << ": " << pair.second << " (" - << pair.second / total * 100.0 << "%)"; - } - } - - static OpCost& get() { - static OpCost instance; - return instance; - } - - std::map table; -}; - -static std::string get_opr_name(const physical::PhysicalOpr& opr) { - switch (opr.opr().op_kind_case()) { - case physical::PhysicalOpr_Operator::OpKindCase::kScan: { - return "scan"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kEdge: { - return "edge_expand"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kVertex: { - return "get_v"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kOrderBy: { - return "order_by"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kProject: { - return "project"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kSink: { - return "sink"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kDedup: { - return "dedup"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kGroupBy: { - return "group_by"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kSelect: { - return "select"; - } - case physical::PhysicalOpr_Operator::OpKindCase::kPath: { - return "path"; - } - default: - return "unknown - " + - std::to_string(static_cast(opr.opr().op_kind_case())); - } -} - -bl::result runtime_eval_impl( - const physical::PhysicalPlan& plan, Context&& ctx, - const ReadTransaction& txn, - const std::map& params) { - Context ret = ctx; - - auto& op_cost = OpCost::get().table; - - int opr_num = plan.plan_size(); - bool terminate = false; - for (int i = 0; i < opr_num; ++i) { - const physical::PhysicalOpr& opr = plan.plan(i); - double t = -grape::GetCurrentTime(); - assert(opr.has_opr()); - switch (opr.opr().op_kind_case()) { - LOG(INFO) << "eval: " << get_opr_name(opr); - case physical::PhysicalOpr_Operator::OpKindCase::kScan: { - BOOST_LEAF_ASSIGN(ret, eval_scan(opr.opr().scan(), txn, params)); - t += grape::GetCurrentTime(); - op_cost["scan"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kEdge: { - CHECK_EQ(opr.meta_data_size(), 1); - BOOST_LEAF_ASSIGN( - ret, eval_edge_expand(opr.opr().edge(), txn, std::move(ret), params, - opr.meta_data(0))); - t += grape::GetCurrentTime(); - op_cost["edge_expand"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kVertex: { - BOOST_LEAF_ASSIGN( - ret, eval_get_v(opr.opr().vertex(), txn, std::move(ret), params)); - t += grape::GetCurrentTime(); - op_cost["get_v"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kProject: { - std::vector data_types; - if (opr.meta_data_size() == opr.opr().project().mappings_size()) { - for (int i = 0; i < opr.meta_data_size(); ++i) { - if (opr.meta_data(i).type().type_case() == - common::IrDataType::TypeCase::TYPE_NOT_SET) { - LOG(INFO) << "type not set"; - } - data_types.push_back(opr.meta_data(i).type()); - } - } - BOOST_LEAF_ASSIGN(ret, eval_project(opr.opr().project(), txn, - std::move(ret), params, data_types)); - t += grape::GetCurrentTime(); - op_cost["project"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kOrderBy: { - BOOST_LEAF_ASSIGN( - ret, eval_order_by(opr.opr().order_by(), txn, std::move(ret))); - t += grape::GetCurrentTime(); - op_cost["order_by"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kGroupBy: { - BOOST_LEAF_ASSIGN( - ret, eval_group_by(opr.opr().group_by(), txn, std::move(ret))); - t += grape::GetCurrentTime(); - op_cost["group_by"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kDedup: { - BOOST_LEAF_ASSIGN(ret, - eval_dedup(opr.opr().dedup(), txn, std::move(ret))); - t += grape::GetCurrentTime(); - op_cost["dedup"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kSelect: { - BOOST_LEAF_ASSIGN( - ret, eval_select(opr.opr().select(), txn, std::move(ret), params)); - t += grape::GetCurrentTime(); - op_cost["select"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kPath: { - if ((i + 1) < opr_num) { - const physical::PhysicalOpr& next_opr = plan.plan(i + 1); - if (next_opr.opr().has_vertex() && - opr.opr().path().result_opt() == - physical::PathExpand_ResultOpt::PathExpand_ResultOpt_END_V && - opr.opr().path().base().edge_expand().expand_opt() == - physical::EdgeExpand_ExpandOpt::EdgeExpand_ExpandOpt_VERTEX) { - int alias = -1; - if (next_opr.opr().vertex().has_alias()) { - alias = next_opr.opr().vertex().alias().value(); - } - BOOST_LEAF_ASSIGN( - ret, eval_path_expand_v(opr.opr().path(), txn, std::move(ret), - params, opr.meta_data(0), alias)); - ++i; - } else { - int alias = -1; - if (opr.opr().path().has_alias()) { - alias = opr.opr().path().alias().value(); - } - BOOST_LEAF_ASSIGN( - ret, eval_path_expand_p(opr.opr().path(), txn, std::move(ret), - params, opr.meta_data(0), alias)); - } - } else { - LOG(ERROR) << "Path Expand to Path is currently not supported"; - RETURN_UNSUPPORTED_ERROR( - "Path Expand to Path is currently not supported"); - } - t += grape::GetCurrentTime(); - op_cost["path_expand"] += t; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kSink: { - terminate = true; - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kRoot: { - // do nothing - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kJoin: { - auto op = opr.opr().join(); - auto ret_dup = ret.dup(); - BOOST_LEAF_AUTO( - ctx, runtime_eval_impl(op.left_plan(), std::move(ret), txn, params)); - BOOST_LEAF_AUTO(ctx2, runtime_eval_impl(op.right_plan(), - std::move(ret_dup), txn, params)); - BOOST_LEAF_ASSIGN(ret, eval_join(op, std::move(ctx), std::move(ctx2))); - - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kIntersect: { - auto op = opr.opr().intersect(); - size_t num = op.sub_plans_size(); - std::vector ctxs; - ret.push_idx_col(); - for (size_t i = 0; i < num; ++i) { - if (i + 1 < num) { - auto ret_dup = ret.dup(); - BOOST_LEAF_AUTO( - ctx, runtime_eval_impl(op.sub_plans(i), std::move(ret_dup), txn, - params)); - ctxs.push_back(std::move(ctx)); - } else { - BOOST_LEAF_AUTO(ctx, runtime_eval_impl(op.sub_plans(i), - std::move(ret), txn, params)); - ctxs.push_back(std::move(ctx)); - } - } - BOOST_LEAF_ASSIGN(ret, eval_intersect(txn, op, std::move(ctxs))); - } break; - case physical::PhysicalOpr_Operator::OpKindCase::kLimit: { - BOOST_LEAF_ASSIGN(ret, eval_limit(opr.opr().limit(), std::move(ret))); - } break; - - default: - LOG(ERROR) << "Unknown operator type: " - << static_cast(opr.opr().op_kind_case()); - RETURN_UNSUPPORTED_ERROR( - "Unknown operator type: " + - std::to_string(static_cast(opr.opr().op_kind_case()))); - break; - } - if (terminate) { - break; - } - } - return ret; -} - -bl::result runtime_eval( - const physical::PhysicalPlan& plan, const ReadTransaction& txn, - const std::map& params) { - return runtime_eval_impl(plan, Context(), txn, params); -} - -} // namespace runtime - -} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/adhoc/runtime.h b/flex/engines/graph_db/runtime/adhoc/runtime.h index 9f2e93aa204f..0e8080f07d76 100644 --- a/flex/engines/graph_db/runtime/adhoc/runtime.h +++ b/flex/engines/graph_db/runtime/adhoc/runtime.h @@ -26,9 +26,237 @@ namespace gs { namespace runtime { +class OpCost { + public: + OpCost() {} + ~OpCost() { + double total = 0; + for (auto& pair : table) { + total += pair.second; + } + LOG(INFO) << "op elapsed time: "; + for (auto& pair : table) { + LOG(INFO) << "\t" << pair.first << ": " << pair.second << " (" + << pair.second / total * 100.0 << "%)"; + } + } + + static OpCost& get() { + static OpCost instance; + return instance; + } + + std::map table; +}; + +static std::string get_opr_name(const physical::PhysicalOpr& opr) { + switch (opr.opr().op_kind_case()) { + case physical::PhysicalOpr_Operator::OpKindCase::kScan: { + return "scan"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kEdge: { + return "edge_expand"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kVertex: { + return "get_v"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kOrderBy: { + return "order_by"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kProject: { + return "project"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kSink: { + return "sink"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kDedup: { + return "dedup"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kGroupBy: { + return "group_by"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kSelect: { + return "select"; + } + case physical::PhysicalOpr_Operator::OpKindCase::kPath: { + return "path"; + } + default: + return "unknown - " + + std::to_string(static_cast(opr.opr().op_kind_case())); + } +} + +template +bl::result runtime_eval_impl( + const physical::PhysicalPlan& plan, Context&& ctx, + const GraphInterface& txn, + const std::map& params) { + Context ret = ctx; + + auto& op_cost = OpCost::get().table; + + int opr_num = plan.plan_size(); + bool terminate = false; + for (int i = 0; i < opr_num; ++i) { + const physical::PhysicalOpr& opr = plan.plan(i); + double t = -grape::GetCurrentTime(); + assert(opr.has_opr()); + switch (opr.opr().op_kind_case()) { + LOG(INFO) << "eval: " << get_opr_name(opr); + case physical::PhysicalOpr_Operator::OpKindCase::kScan: { + BOOST_LEAF_ASSIGN(ret, eval_scan(opr.opr().scan(), txn, params)); + t += grape::GetCurrentTime(); + op_cost["scan"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kEdge: { + CHECK_EQ(opr.meta_data_size(), 1); + BOOST_LEAF_ASSIGN( + ret, eval_edge_expand(opr.opr().edge(), txn, std::move(ret), params, + opr.meta_data(0))); + t += grape::GetCurrentTime(); + op_cost["edge_expand"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kVertex: { + BOOST_LEAF_ASSIGN( + ret, eval_get_v(opr.opr().vertex(), txn, std::move(ret), params)); + t += grape::GetCurrentTime(); + op_cost["get_v"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kProject: { + std::vector data_types; + if (opr.meta_data_size() == opr.opr().project().mappings_size()) { + for (int i = 0; i < opr.meta_data_size(); ++i) { + if (opr.meta_data(i).type().type_case() == + common::IrDataType::TypeCase::TYPE_NOT_SET) { + LOG(INFO) << "type not set"; + } + data_types.push_back(opr.meta_data(i).type()); + } + } + BOOST_LEAF_ASSIGN(ret, eval_project(opr.opr().project(), txn, + std::move(ret), params, data_types)); + t += grape::GetCurrentTime(); + op_cost["project"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kOrderBy: { + BOOST_LEAF_ASSIGN( + ret, eval_order_by(opr.opr().order_by(), txn, std::move(ret))); + t += grape::GetCurrentTime(); + op_cost["order_by"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kGroupBy: { + BOOST_LEAF_ASSIGN( + ret, eval_group_by(opr.opr().group_by(), txn, std::move(ret))); + t += grape::GetCurrentTime(); + op_cost["group_by"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kDedup: { + BOOST_LEAF_ASSIGN(ret, + eval_dedup(opr.opr().dedup(), txn, std::move(ret))); + t += grape::GetCurrentTime(); + op_cost["dedup"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kSelect: { + BOOST_LEAF_ASSIGN( + ret, eval_select(opr.opr().select(), txn, std::move(ret), params)); + t += grape::GetCurrentTime(); + op_cost["select"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kPath: { + if ((i + 1) < opr_num) { + const physical::PhysicalOpr& next_opr = plan.plan(i + 1); + if (next_opr.opr().has_vertex() && + opr.opr().path().result_opt() == + physical::PathExpand_ResultOpt::PathExpand_ResultOpt_END_V && + opr.opr().path().base().edge_expand().expand_opt() == + physical::EdgeExpand_ExpandOpt::EdgeExpand_ExpandOpt_VERTEX) { + int alias = -1; + if (next_opr.opr().vertex().has_alias()) { + alias = next_opr.opr().vertex().alias().value(); + } + BOOST_LEAF_ASSIGN( + ret, eval_path_expand_v(opr.opr().path(), txn, std::move(ret), + params, opr.meta_data(0), alias)); + ++i; + } else { + int alias = -1; + if (opr.opr().path().has_alias()) { + alias = opr.opr().path().alias().value(); + } + BOOST_LEAF_ASSIGN( + ret, eval_path_expand_p(opr.opr().path(), txn, std::move(ret), + params, opr.meta_data(0), alias)); + } + } else { + LOG(ERROR) << "Path Expand to Path is currently not supported"; + RETURN_UNSUPPORTED_ERROR( + "Path Expand to Path is currently not supported"); + } + t += grape::GetCurrentTime(); + op_cost["path_expand"] += t; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kSink: { + terminate = true; + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kRoot: { + // do nothing + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kJoin: { + auto op = opr.opr().join(); + auto ret_dup = ret.dup(); + BOOST_LEAF_AUTO( + ctx, runtime_eval_impl(op.left_plan(), std::move(ret), txn, params)); + BOOST_LEAF_AUTO(ctx2, runtime_eval_impl(op.right_plan(), + std::move(ret_dup), txn, params)); + BOOST_LEAF_ASSIGN(ret, eval_join(op, std::move(ctx), std::move(ctx2))); + + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kIntersect: { + auto op = opr.opr().intersect(); + size_t num = op.sub_plans_size(); + std::vector ctxs; + ret.push_idx_col(); + for (size_t i = 0; i < num; ++i) { + if (i + 1 < num) { + auto ret_dup = ret.dup(); + BOOST_LEAF_AUTO( + ctx, runtime_eval_impl(op.sub_plans(i), std::move(ret_dup), txn, + params)); + ctxs.push_back(std::move(ctx)); + } else { + BOOST_LEAF_AUTO(ctx, runtime_eval_impl(op.sub_plans(i), + std::move(ret), txn, params)); + ctxs.push_back(std::move(ctx)); + } + } + BOOST_LEAF_ASSIGN(ret, eval_intersect(txn, op, std::move(ctxs))); + } break; + case physical::PhysicalOpr_Operator::OpKindCase::kLimit: { + BOOST_LEAF_ASSIGN(ret, eval_limit(opr.opr().limit(), std::move(ret))); + } break; + + default: + LOG(ERROR) << "Unknown operator type: " + << static_cast(opr.opr().op_kind_case()); + RETURN_UNSUPPORTED_ERROR( + "Unknown operator type: " + + std::to_string(static_cast(opr.opr().op_kind_case()))); + break; + } + if (terminate) { + break; + } + } + return ret; +} + +template bl::result runtime_eval( - const physical::PhysicalPlan& plan, const ReadTransaction& txn, - const std::map& params); + const physical::PhysicalPlan& plan, const GraphInterface& txn, + const std::map& params) { + return runtime_eval_impl(plan, Context(), txn, params); +} } // namespace runtime diff --git a/flex/engines/graph_db/runtime/adhoc/utils.cc b/flex/engines/graph_db/runtime/adhoc/utils.cc deleted file mode 100644 index bd5135b0d2ca..000000000000 --- a/flex/engines/graph_db/runtime/adhoc/utils.cc +++ /dev/null @@ -1,569 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ -#include "flex/engines/graph_db/runtime/adhoc/utils.h" -#include "flex/engines/graph_db/runtime/common/columns/value_columns.h" -#include "flex/engines/graph_db/runtime/common/columns/vertex_columns.h" - -namespace gs { - -namespace runtime { - -Direction parse_direction(const physical::EdgeExpand_Direction& dir) { - if (dir == physical::EdgeExpand_Direction_OUT) { - return Direction::kOut; - } else if (dir == physical::EdgeExpand_Direction_IN) { - return Direction::kIn; - } else if (dir == physical::EdgeExpand_Direction_BOTH) { - return Direction::kBoth; - } - LOG(FATAL) << "not support..."; - return Direction::kOut; -} - -std::vector parse_tables(const algebra::QueryParams& query_params) { - std::vector tables; - int tn = query_params.tables_size(); - for (int i = 0; i < tn; ++i) { - const common::NameOrId& table = query_params.tables(i); - tables.push_back(static_cast(table.id())); - } - return tables; -} - -std::vector parse_label_triplets( - const physical::PhysicalOpr_MetaData& meta) { - std::vector labels; - if (meta.has_type()) { - const common::IrDataType& t = meta.type(); - if (t.has_graph_type()) { - const common::GraphDataType& gt = t.graph_type(); - if (gt.element_opt() == common::GraphDataType_GraphElementOpt:: - GraphDataType_GraphElementOpt_EDGE) { - int label_num = gt.graph_data_type_size(); - for (int label_i = 0; label_i < label_num; ++label_i) { - const common::GraphDataType_GraphElementLabel& gdt = - gt.graph_data_type(label_i).label(); - labels.emplace_back(static_cast(gdt.src_label().value()), - static_cast(gdt.dst_label().value()), - static_cast(gdt.label())); - } - } - } - } - return labels; -} - -std::shared_ptr create_column( - const common::IrDataType& data_type) { - switch (data_type.type_case()) { - case common::IrDataType::kDataType: - LOG(FATAL) << "not support"; - break; - case common::IrDataType::kGraphType: { - const common::GraphDataType& graph_data_type = data_type.graph_type(); - common::GraphDataType_GraphElementOpt elem_opt = - graph_data_type.element_opt(); - int label_num = graph_data_type.graph_data_type_size(); - if (elem_opt == common::GraphDataType_GraphElementOpt:: - GraphDataType_GraphElementOpt_VERTEX) { - if (label_num == 1) { - label_t v_label = static_cast( - graph_data_type.graph_data_type(0).label().label()); - return std::make_shared(v_label); - } else if (label_num > 1) { - return std::make_shared(); - } else { - LOG(FATAL) << "unexpected type"; - } - } else if (elem_opt == common::GraphDataType_GraphElementOpt:: - GraphDataType_GraphElementOpt_EDGE) { - LOG(FATAL) << "unexpected type"; - } else { - LOG(FATAL) << "unexpected type"; - } - } break; - default: - LOG(FATAL) << "unexpected type"; - break; - } - return nullptr; -} - -std::shared_ptr create_column_beta(RTAnyType type) { - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>(); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared>(); - case RTAnyType::RTAnyTypeImpl::kVertex: - return std::make_shared(); - default: - LOG(FATAL) << "unsupport type: " << static_cast(type.type_enum_); - break; - } - return nullptr; -} - -std::shared_ptr create_column_builder(RTAnyType type) { - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>(); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared>(); - case RTAnyType::RTAnyTypeImpl::kVertex: - return std::make_shared(); - case RTAnyType::RTAnyTypeImpl::kI32Value: - return std::make_shared>(); - case RTAnyType::RTAnyTypeImpl::kDate32: - return std::make_shared>(); - case RTAnyType::RTAnyTypeImpl::kU64Value: - return std::make_shared>(); - case RTAnyType::RTAnyTypeImpl::kBoolValue: - // fix me - return std::make_shared>(); - case RTAnyType::RTAnyTypeImpl::kEdge: - return std::make_shared(); - case RTAnyType::RTAnyTypeImpl::kStringSetValue: - return std::make_shared>>(); - default: - LOG(FATAL) << "unsupport type: " << static_cast(type.type_enum_); - break; - } - return nullptr; -} - -std::shared_ptr build_optional_column( - const common::IrDataType& data_type, const Expr& expr, size_t row_num) { - switch (data_type.type_case()) { - case common::IrDataType::kDataType: { - switch (data_type.data_type()) { - case common::DataType::INT64: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(v.as_int64(), true); - } - } - - return builder.finish(); - } break; - case common::DataType::INT32: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(v.as_int32(), true); - } - } - - return builder.finish(); - } break; - case common::DataType::DOUBLE: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(v.as_double(), true); - } - } - - return builder.finish(); - } break; - case common::DataType::BOOLEAN: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(v.as_bool(), true); - } - } - - return builder.finish(); - } break; - case common::DataType::STRING: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(std::string(v.as_string()), true); - } - } - - return builder.finish(); - } break; - case common::DataType::TIMESTAMP: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(v.as_date32(), true); - } - } - - return builder.finish(); - } break; - - default: { - LOG(FATAL) << "not support" - << common::DataType_Name(data_type.data_type()); - break; - } - } - } - case common::IrDataType::TYPE_NOT_SET: { - return build_column_beta(expr, row_num); - } break; - default: { - LOG(FATAL) << "not support" << data_type.DebugString(); - break; - } - } - return nullptr; -} - -std::shared_ptr build_column( - const common::IrDataType& data_type, const Expr& expr, size_t row_num) { - if (expr.is_optional()) { - return build_optional_column(data_type, expr, row_num); - } - switch (data_type.type_case()) { - case common::IrDataType::kDataType: { - switch (data_type.data_type()) { - case common::DataType::INT64: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i).as_int64(); - builder.push_back_opt(v); - } - - return builder.finish(); - } break; - case common::DataType::INT32: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i).as_int32(); - builder.push_back_opt(v); - } - - return builder.finish(); - } break; - case common::DataType::STRING: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i).as_string(); - builder.push_back_opt(std::string(v)); - } - - return builder.finish(); - } break; - case common::DataType::DATE32: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i).as_date32(); - builder.push_back_opt(v); - } - - return builder.finish(); - } break; - case common::DataType::STRING_ARRAY: { - ValueColumnBuilder> builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - const auto& v = expr.eval_path(i).as_string_set(); - builder.push_back_opt(v); - } - - return builder.finish(); - } break; - case common::DataType::TIMESTAMP: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i).as_date32(); - builder.push_back_opt(v); - } - - return builder.finish(); - } break; - case common::DataType::BOOLEAN: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i).as_bool(); - builder.push_back_opt(v); - } - return builder.finish(); - } break; - case common::DataType::DOUBLE: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i).as_double(); - builder.push_back_opt(v); - } - return builder.finish(); - } break; - default: { - LOG(FATAL) << "not support: " - << common::DataType_Name(data_type.data_type()); - } - } - } break; - case common::IrDataType::kGraphType: { - const common::GraphDataType& graph_data_type = data_type.graph_type(); - common::GraphDataType_GraphElementOpt elem_opt = - graph_data_type.element_opt(); - int label_num = graph_data_type.graph_data_type_size(); - if (elem_opt == common::GraphDataType_GraphElementOpt:: - GraphDataType_GraphElementOpt_VERTEX) { - if (label_num == 1) { - label_t v_label = static_cast( - graph_data_type.graph_data_type(0).label().label()); - SLVertexColumnBuilder builder(v_label); - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_opt(expr.eval_path(i).as_vertex().second); - } - - return builder.finish(); - } else if (label_num > 1) { - MLVertexColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_vertex(expr.eval_path(i).as_vertex()); - } - - return builder.finish(); - } else { - LOG(FATAL) << "unexpected type"; - } - } else if (elem_opt == common::GraphDataType_GraphElementOpt:: - GraphDataType_GraphElementOpt_EDGE) { - // LOG(FATAL) << "unexpected type"; - BDMLEdgeColumnBuilder builder; - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_elem(expr.eval_path(i)); - } - return builder.finish(); - } else { - LOG(FATAL) << "unexpected type"; - } - } break; - case common::IrDataType::TYPE_NOT_SET: { - return build_column_beta(expr, row_num); - } break; - default: - LOG(FATAL) << "unexpected type" - << common::DataType_Name(data_type.data_type()); - break; - } - - return nullptr; -} - -std::shared_ptr build_optional_column_beta(const Expr& expr, - size_t row_num) { - switch (expr.type().type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(v.as_int64(), true); - } - } - - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kI32Value: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(v.as_int32(), true); - } - } - - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kF64Value: { - OptionalValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i, 0); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_opt(v.as_double(), true); - } - } - - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kMap: { - auto builder = expr.builder(); - for (size_t i = 0; i < row_num; ++i) { - builder->push_back_elem(expr.eval_path(i, 0)); - } - return builder->finish(); - } break; - default: { - LOG(FATAL) << "not support"; - break; - } - } - return nullptr; -} - -std::shared_ptr build_column_beta(const Expr& expr, - size_t row_num) { - if (expr.is_optional()) { - return build_optional_column_beta(expr, row_num); - } - switch (expr.type().type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_opt(expr.eval_path(i).as_int64()); - } - - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kStringValue: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_opt(std::string(expr.eval_path(i).as_string())); - } - - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kDate32: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_opt(expr.eval_path(i).as_date32()); - } - - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kVertex: { - MLVertexColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_vertex(expr.eval_path(i).as_vertex()); - } - - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kI32Value: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_opt(expr.eval_path(i).as_int32()); - } - - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kF64Value: { - ValueColumnBuilder builder; - builder.reserve(row_num); - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_opt(expr.eval_path(i).as_double()); - } - return builder.finish(); - } break; - case RTAnyType::RTAnyTypeImpl::kEdge: { - BDMLEdgeColumnBuilder builder; - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_elem(expr.eval_path(i)); - } - return builder.finish(); - } - case RTAnyType::RTAnyTypeImpl::kTuple: { - if (expr.type().null_able_) { - OptionalValueColumnBuilder builder; - for (size_t i = 0; i < row_num; ++i) { - auto v = expr.eval_path(i); - if (v.is_null()) { - builder.push_back_null(); - } else { - builder.push_back_elem(v); - } - } - return builder.finish(); - } else { - ValueColumnBuilder builder; - for (size_t i = 0; i < row_num; ++i) { - builder.push_back_elem(expr.eval_path(i)); - } - return builder.finish(); - } - } - case RTAnyType::RTAnyTypeImpl::kList: { - auto builder = expr.builder(); - for (size_t i = 0; i < row_num; ++i) { - builder->push_back_elem(expr.eval_path(i)); - } - return builder->finish(); - } - case RTAnyType::RTAnyTypeImpl::kMap: { - auto builder = expr.builder(); - for (size_t i = 0; i < row_num; ++i) { - builder->push_back_elem(expr.eval_path(i)); - } - return builder->finish(); - } - default: - LOG(FATAL) << "not support - " << static_cast(expr.type().type_enum_); - break; - } - - return nullptr; -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/adhoc/utils.h b/flex/engines/graph_db/runtime/adhoc/utils.h index 41ed732c9af5..ef934efb1c5e 100644 --- a/flex/engines/graph_db/runtime/adhoc/utils.h +++ b/flex/engines/graph_db/runtime/adhoc/utils.h @@ -29,25 +29,554 @@ namespace gs { namespace runtime { -Direction parse_direction(const physical::EdgeExpand_Direction& dir); +template +std::shared_ptr build_optional_column_beta( + const Expr& expr, size_t row_num) { + switch (expr.type().type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(v.as_int64(), true); + } + } -std::vector parse_tables(const algebra::QueryParams& query_params); + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kI32Value: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(v.as_int32(), true); + } + } + + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kF64Value: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(v.as_double(), true); + } + } + + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kMap: { + auto builder = expr.builder(); + for (size_t i = 0; i < row_num; ++i) { + builder->push_back_elem(expr.eval_path(i, 0)); + } + return builder->finish(); + } break; + default: { + LOG(FATAL) << "not support"; + break; + } + } + return nullptr; +} + +template +std::shared_ptr build_column_beta(const Expr& expr, + size_t row_num) { + if (expr.is_optional()) { + return build_optional_column_beta(expr, row_num); + } + switch (expr.type().type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_opt(expr.eval_path(i).as_int64()); + } + + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kStringValue: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_opt(std::string(expr.eval_path(i).as_string())); + } + + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kDate32: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_opt(expr.eval_path(i).as_date32()); + } + + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kVertex: { + MLVertexColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_vertex(expr.eval_path(i).as_vertex()); + } + + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kI32Value: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_opt(expr.eval_path(i).as_int32()); + } + + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kF64Value: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_opt(expr.eval_path(i).as_double()); + } + return builder.finish(); + } break; + case RTAnyType::RTAnyTypeImpl::kEdge: { + BDMLEdgeColumnBuilder builder; + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_elem(expr.eval_path(i)); + } + return builder.finish(); + } + case RTAnyType::RTAnyTypeImpl::kTuple: { + if (expr.type().null_able_) { + OptionalValueColumnBuilder builder; + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_elem(v); + } + } + return builder.finish(); + } else { + ValueColumnBuilder builder; + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_elem(expr.eval_path(i)); + } + return builder.finish(); + } + } + case RTAnyType::RTAnyTypeImpl::kList: { + auto builder = expr.builder(); + for (size_t i = 0; i < row_num; ++i) { + builder->push_back_elem(expr.eval_path(i)); + } + return builder->finish(); + } + case RTAnyType::RTAnyTypeImpl::kMap: { + auto builder = expr.builder(); + for (size_t i = 0; i < row_num; ++i) { + builder->push_back_elem(expr.eval_path(i)); + } + return builder->finish(); + } + default: + LOG(FATAL) << "not support - " << static_cast(expr.type().type_enum_); + break; + } + + return nullptr; +} +Direction parse_direction(const physical::EdgeExpand_Direction& dir) { + if (dir == physical::EdgeExpand_Direction_OUT) { + return Direction::kOut; + } else if (dir == physical::EdgeExpand_Direction_IN) { + return Direction::kIn; + } else if (dir == physical::EdgeExpand_Direction_BOTH) { + return Direction::kBoth; + } + LOG(FATAL) << "not support..."; + return Direction::kOut; +} + +std::vector parse_tables(const algebra::QueryParams& query_params) { + std::vector tables; + int tn = query_params.tables_size(); + for (int i = 0; i < tn; ++i) { + const common::NameOrId& table = query_params.tables(i); + tables.push_back(static_cast(table.id())); + } + return tables; +} std::vector parse_label_triplets( - const physical::PhysicalOpr_MetaData& meta); + const physical::PhysicalOpr_MetaData& meta) { + std::vector labels; + if (meta.has_type()) { + const common::IrDataType& t = meta.type(); + if (t.has_graph_type()) { + const common::GraphDataType& gt = t.graph_type(); + if (gt.element_opt() == common::GraphDataType_GraphElementOpt:: + GraphDataType_GraphElementOpt_EDGE) { + int label_num = gt.graph_data_type_size(); + for (int label_i = 0; label_i < label_num; ++label_i) { + const common::GraphDataType_GraphElementLabel& gdt = + gt.graph_data_type(label_i).label(); + labels.emplace_back(static_cast(gdt.src_label().value()), + static_cast(gdt.dst_label().value()), + static_cast(gdt.label())); + } + } + } + } + return labels; +} std::shared_ptr create_column( - const common::IrDataType& data_type); + const common::IrDataType& data_type) { + switch (data_type.type_case()) { + case common::IrDataType::kDataType: + LOG(FATAL) << "not support"; + break; + case common::IrDataType::kGraphType: { + const common::GraphDataType& graph_data_type = data_type.graph_type(); + common::GraphDataType_GraphElementOpt elem_opt = + graph_data_type.element_opt(); + int label_num = graph_data_type.graph_data_type_size(); + if (elem_opt == common::GraphDataType_GraphElementOpt:: + GraphDataType_GraphElementOpt_VERTEX) { + if (label_num == 1) { + label_t v_label = static_cast( + graph_data_type.graph_data_type(0).label().label()); + return std::make_shared(v_label); + } else if (label_num > 1) { + return std::make_shared(); + } else { + LOG(FATAL) << "unexpected type"; + } + } else if (elem_opt == common::GraphDataType_GraphElementOpt:: + GraphDataType_GraphElementOpt_EDGE) { + LOG(FATAL) << "unexpected type"; + } else { + LOG(FATAL) << "unexpected type"; + } + } break; + default: + LOG(FATAL) << "unexpected type"; + break; + } + return nullptr; +} + +std::shared_ptr create_column_beta(RTAnyType type) { + switch (type.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return std::make_shared>(); + case RTAnyType::RTAnyTypeImpl::kStringValue: + return std::make_shared>(); + case RTAnyType::RTAnyTypeImpl::kVertex: + return std::make_shared(); + default: + LOG(FATAL) << "unsupport type: " << static_cast(type.type_enum_); + break; + } + return nullptr; +} + +std::shared_ptr create_column_builder(RTAnyType type) { + switch (type.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return std::make_shared>(); + case RTAnyType::RTAnyTypeImpl::kStringValue: + return std::make_shared>(); + case RTAnyType::RTAnyTypeImpl::kVertex: + return std::make_shared(); + case RTAnyType::RTAnyTypeImpl::kI32Value: + return std::make_shared>(); + case RTAnyType::RTAnyTypeImpl::kDate32: + return std::make_shared>(); + case RTAnyType::RTAnyTypeImpl::kU64Value: + return std::make_shared>(); + case RTAnyType::RTAnyTypeImpl::kBoolValue: + // fix me + return std::make_shared>(); + case RTAnyType::RTAnyTypeImpl::kEdge: + return std::make_shared(); + case RTAnyType::RTAnyTypeImpl::kStringSetValue: + return std::make_shared>>(); + default: + LOG(FATAL) << "unsupport type: " << static_cast(type.type_enum_); + break; + } + return nullptr; +} + +template +std::shared_ptr build_optional_column( + const common::IrDataType& data_type, const Expr& expr, + size_t row_num) { + switch (data_type.type_case()) { + case common::IrDataType::kDataType: { + switch (data_type.data_type()) { + case common::DataType::INT64: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(v.as_int64(), true); + } + } -std::shared_ptr create_column_beta(RTAnyType type); + return builder.finish(); + } break; + case common::DataType::INT32: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(v.as_int32(), true); + } + } + return builder.finish(); + } break; + case common::DataType::DOUBLE: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(v.as_double(), true); + } + } + + return builder.finish(); + } break; + case common::DataType::BOOLEAN: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(v.as_bool(), true); + } + } + + return builder.finish(); + } break; + case common::DataType::STRING: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(std::string(v.as_string()), true); + } + } + + return builder.finish(); + } break; + case common::DataType::TIMESTAMP: { + OptionalValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i, 0); + if (v.is_null()) { + builder.push_back_null(); + } else { + builder.push_back_opt(v.as_date32(), true); + } + } + + return builder.finish(); + } break; + + default: { + LOG(FATAL) << "not support" + << common::DataType_Name(data_type.data_type()); + break; + } + } + } + case common::IrDataType::TYPE_NOT_SET: { + return build_column_beta(expr, row_num); + } break; + default: { + LOG(FATAL) << "not support" << data_type.DebugString(); + break; + } + } + return nullptr; +} + +template std::shared_ptr build_column( - const common::IrDataType& data_type, const Expr& expr, size_t row_num); + const common::IrDataType& data_type, const Expr& expr, + size_t row_num) { + if (expr.is_optional()) { + return build_optional_column(data_type, expr, row_num); + } + switch (data_type.type_case()) { + case common::IrDataType::kDataType: { + switch (data_type.data_type()) { + case common::DataType::INT64: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i).as_int64(); + builder.push_back_opt(v); + } + + return builder.finish(); + } break; + case common::DataType::INT32: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i).as_int32(); + builder.push_back_opt(v); + } + + return builder.finish(); + } break; + case common::DataType::STRING: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i).as_string(); + builder.push_back_opt(std::string(v)); + } + + return builder.finish(); + } break; + case common::DataType::DATE32: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i).as_date32(); + builder.push_back_opt(v); + } + + return builder.finish(); + } break; + case common::DataType::STRING_ARRAY: { + ValueColumnBuilder> builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + const auto& v = expr.eval_path(i).as_string_set(); + builder.push_back_opt(v); + } + + return builder.finish(); + } break; + case common::DataType::TIMESTAMP: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i).as_date32(); + builder.push_back_opt(v); + } + + return builder.finish(); + } break; + case common::DataType::BOOLEAN: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i).as_bool(); + builder.push_back_opt(v); + } + return builder.finish(); + } break; + case common::DataType::DOUBLE: { + ValueColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + auto v = expr.eval_path(i).as_double(); + builder.push_back_opt(v); + } + return builder.finish(); + } break; + default: { + LOG(FATAL) << "not support: " + << common::DataType_Name(data_type.data_type()); + } + } + } break; + case common::IrDataType::kGraphType: { + const common::GraphDataType& graph_data_type = data_type.graph_type(); + common::GraphDataType_GraphElementOpt elem_opt = + graph_data_type.element_opt(); + int label_num = graph_data_type.graph_data_type_size(); + if (elem_opt == common::GraphDataType_GraphElementOpt:: + GraphDataType_GraphElementOpt_VERTEX) { + if (label_num == 1) { + label_t v_label = static_cast( + graph_data_type.graph_data_type(0).label().label()); + SLVertexColumnBuilder builder(v_label); + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_opt(expr.eval_path(i).as_vertex().second); + } + + return builder.finish(); + } else if (label_num > 1) { + MLVertexColumnBuilder builder; + builder.reserve(row_num); + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_vertex(expr.eval_path(i).as_vertex()); + } -std::shared_ptr build_column_beta(const Expr& expr, - size_t row_num); + return builder.finish(); + } else { + LOG(FATAL) << "unexpected type"; + } + } else if (elem_opt == common::GraphDataType_GraphElementOpt:: + GraphDataType_GraphElementOpt_EDGE) { + // LOG(FATAL) << "unexpected type"; + BDMLEdgeColumnBuilder builder; + for (size_t i = 0; i < row_num; ++i) { + builder.push_back_elem(expr.eval_path(i)); + } + return builder.finish(); + } else { + LOG(FATAL) << "unexpected type"; + } + } break; + case common::IrDataType::TYPE_NOT_SET: { + return build_column_beta(expr, row_num); + } break; + default: + LOG(FATAL) << "unexpected type" + << common::DataType_Name(data_type.data_type()); + break; + } -std::shared_ptr create_column_builder(RTAnyType type); + return nullptr; +} } // namespace runtime diff --git a/flex/engines/graph_db/runtime/adhoc/var.cc b/flex/engines/graph_db/runtime/adhoc/var.cc deleted file mode 100644 index 3f581aa80d4f..000000000000 --- a/flex/engines/graph_db/runtime/adhoc/var.cc +++ /dev/null @@ -1,210 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/adhoc/var.h" -#include "flex/engines/graph_db/runtime/common/accessors.h" -#include "flex/engines/graph_db/runtime/common/columns/edge_columns.h" -#include "flex/engines/graph_db/runtime/common/columns/i_context_column.h" -#include "flex/engines/graph_db/runtime/common/columns/vertex_columns.h" - -namespace gs { - -namespace runtime { - -Var::Var(const ReadTransaction& txn, const Context& ctx, - const common::Variable& pb, VarType var_type) - : getter_(nullptr) { - int tag = -1; - type_ = RTAnyType::kUnknown; - if (pb.has_node_type()) { - type_ = parse_from_ir_data_type(pb.node_type()); - } - if (pb.has_tag()) { - tag = pb.tag().id(); - } - - if (type_ == RTAnyType::kUnknown) { - if (pb.has_tag()) { - tag = pb.tag().id(); - CHECK(ctx.get(tag) != nullptr); - type_ = ctx.get(tag)->elem_type(); - } else if (pb.has_property() && - (pb.property().has_label() || pb.property().has_id())) { - type_ = RTAnyType::kI64Value; - } else { - LOG(FATAL) << "not support"; - } - } - - if (pb.has_tag() || var_type == VarType::kPathVar) { - CHECK(ctx.get(tag) != nullptr) << "tag not found - " << tag; - if (ctx.get(tag)->column_type() == ContextColumnType::kVertex) { - if (pb.has_property()) { - auto& pt = pb.property(); - if (pt.has_id()) { - getter_ = std::make_shared(ctx, tag); - } else if (pt.has_key()) { - if (pt.key().name() == "id") { - if (type_ == RTAnyType::kStringValue) { - getter_ = - std::make_shared>( - txn, ctx, tag); - } else if (type_ == RTAnyType::kI32Value) { - getter_ = std::make_shared>( - txn, ctx, tag); - } else if (type_ == RTAnyType::kI64Value) { - getter_ = std::make_shared>( - txn, ctx, tag); - } else { - LOG(FATAL) << "not support for " - << static_cast(type_.type_enum_); - } - } else { - getter_ = create_vertex_property_path_accessor(txn, ctx, tag, type_, - pt.key().name()); - } - } else if (pt.has_label()) { - getter_ = create_vertex_label_path_accessor(ctx, tag); - } else { - LOG(FATAL) << "xxx, " << pt.item_case(); - } - } else { - getter_ = std::make_shared(ctx, tag); - } - } else if (ctx.get(tag)->column_type() == ContextColumnType::kValue || - ctx.get(tag)->column_type() == - ContextColumnType::kOptionalValue) { - getter_ = create_context_value_accessor(ctx, tag, type_); - } else if (ctx.get(tag)->column_type() == ContextColumnType::kEdge) { - if (pb.has_property()) { - auto& pt = pb.property(); - if (pt.has_key()) { - auto name = pt.key().name(); - getter_ = - create_edge_property_path_accessor(txn, name, ctx, tag, type_); - } else if (pt.has_label()) { - getter_ = create_edge_label_path_accessor(ctx, tag); - } else if (pt.has_id()) { - getter_ = create_edge_global_id_path_accessor(ctx, tag); - } else { - LOG(FATAL) << "not support..."; - } - } else { - getter_ = std::make_shared(ctx, tag); - // LOG(FATAL) << "not support for edge column - " << tag; - } - } else if (ctx.get(tag)->column_type() == ContextColumnType::kPath) { - if (pb.has_property()) { - auto& pt = pb.property(); - if (pt.has_len()) { - getter_ = std::make_shared(ctx, tag); - } else { - LOG(FATAL) << "not support for path column - " << pt.DebugString(); - } - } else { - getter_ = std::make_shared(ctx, tag); - } - } else { - LOG(FATAL) << "not support for " << ctx.get(tag)->column_info(); - } - } else { - if (var_type == VarType::kVertexVar) { - if (pb.has_property()) { - auto& pt = pb.property(); - if (pt.has_id()) { - getter_ = std::make_shared(); - } else if (pt.has_key()) { - if (pt.key().name() == "id") { - if (type_ == RTAnyType::kStringValue) { - getter_ = - std::make_shared>( - txn); - } else if (type_ == RTAnyType::kI32Value) { - getter_ = std::make_shared>(txn); - } else if (type_ == RTAnyType::kI64Value) { - getter_ = std::make_shared>(txn); - } else { - LOG(FATAL) << "not support for " - << static_cast(type_.type_enum_); - } - } else { - getter_ = create_vertex_property_vertex_accessor(txn, type_, - pt.key().name()); - } - } else if (pt.has_label()) { - getter_ = std::make_shared(); - } else { - LOG(FATAL) << "xxx, " << pt.item_case(); - } - } else { - LOG(FATAL) << "not support"; - } - } else if (var_type == VarType::kEdgeVar) { - if (pb.has_property()) { - auto& pt = pb.property(); - if (pt.has_key()) { - auto name = pt.key().name(); - getter_ = create_edge_property_edge_accessor(txn, name, type_); - } else if (pt.has_label()) { - getter_ = create_edge_label_edge_accessor(); - } else if (pt.has_id()) { - getter_ = create_edge_global_id_edge_accessor(); - } else { - LOG(FATAL) << "not support"; - } - } else { - LOG(FATAL) << "not support"; - } - } else { - LOG(FATAL) << "not support"; - } - } -} - -Var::~Var() {} - -RTAny Var::get(size_t path_idx) const { return getter_->eval_path(path_idx); } - -RTAny Var::get(size_t path_idx, int) const { - return getter_->eval_path(path_idx, 0); -} - -RTAny Var::get_vertex(label_t label, vid_t v, size_t idx) const { - return getter_->eval_vertex(label, v, idx); -} - -RTAny Var::get_vertex(label_t label, vid_t v, size_t idx, int) const { - return getter_->eval_vertex(label, v, idx, 0); -} - -RTAny Var::get_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const { - return getter_->eval_edge(label, src, dst, data, idx); -} - -RTAny Var::get_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx, int) const { - return getter_->eval_edge(label, src, dst, data, idx, 0); -} - -RTAnyType Var::type() const { return type_; } - -std::shared_ptr Var::builder() const { - return getter_->builder(); -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/adhoc/var.h b/flex/engines/graph_db/runtime/adhoc/var.h index a209e49b4a24..1b57c4d774e5 100644 --- a/flex/engines/graph_db/runtime/adhoc/var.h +++ b/flex/engines/graph_db/runtime/adhoc/var.h @@ -16,7 +16,7 @@ #ifndef RUNTIME_ADHOC_VAR_H_ #define RUNTIME_ADHOC_VAR_H_ -#include "flex/engines/graph_db/database/read_transaction.h" +#include "flex/engines/graph_db/runtime/adhoc/graph_interface.h" #include "flex/engines/graph_db/runtime/common/accessors.h" #include "flex/engines/graph_db/runtime/common/context.h" @@ -43,24 +43,188 @@ class VarGetterBase { virtual std::string name() const = 0; }; +template class Var { public: - Var(const ReadTransaction& txn, const Context& ctx, - const common::Variable& pb, VarType var_type); - ~Var(); + Var(const GraphInterface& txn, const Context& ctx, + const common::Variable& pb, VarType var_type) + : getter_(nullptr) { + int tag = -1; + type_ = RTAnyType::kUnknown; + if (pb.has_node_type()) { + type_ = parse_from_ir_data_type(pb.node_type()); + } + if (pb.has_tag()) { + tag = pb.tag().id(); + } - RTAny get(size_t path_idx) const; - RTAny get_vertex(label_t label, vid_t v, size_t idx) const; + if (type_ == RTAnyType::kUnknown) { + if (pb.has_tag()) { + tag = pb.tag().id(); + CHECK(ctx.get(tag) != nullptr); + type_ = ctx.get(tag)->elem_type(); + } else if (pb.has_property() && + (pb.property().has_label() || pb.property().has_id())) { + type_ = RTAnyType::kI64Value; + } else { + LOG(FATAL) << "not support"; + } + } + + if (pb.has_tag() || var_type == VarType::kPathVar) { + CHECK(ctx.get(tag) != nullptr) << "tag not found - " << tag; + if (ctx.get(tag)->column_type() == ContextColumnType::kVertex) { + if (pb.has_property()) { + auto& pt = pb.property(); + if (pt.has_id()) { + getter_ = std::make_shared(ctx, tag); + } else if (pt.has_key()) { + if (pt.key().name() == "id") { + if (type_ == RTAnyType::kStringValue) { + getter_ = std::make_shared< + VertexIdPathAccessor>( + txn, ctx, tag); + } else if (type_ == RTAnyType::kI32Value) { + getter_ = + std::make_shared>( + txn, ctx, tag); + } else if (type_ == RTAnyType::kI64Value) { + getter_ = + std::make_shared>( + txn, ctx, tag); + } else { + LOG(FATAL) << "not support for " + << static_cast(type_.type_enum_); + } + } else { + getter_ = create_vertex_property_path_accessor( + txn, ctx, tag, type_, pt.key().name()); + } + } else if (pt.has_label()) { + getter_ = create_vertex_label_path_accessor(ctx, tag); + } else { + LOG(FATAL) << "xxx, " << pt.item_case(); + } + } else { + getter_ = std::make_shared(ctx, tag); + } + } else if (ctx.get(tag)->column_type() == ContextColumnType::kValue || + ctx.get(tag)->column_type() == + ContextColumnType::kOptionalValue) { + getter_ = create_context_value_accessor(ctx, tag, type_); + } else if (ctx.get(tag)->column_type() == ContextColumnType::kEdge) { + if (pb.has_property()) { + auto& pt = pb.property(); + if (pt.has_key()) { + auto name = pt.key().name(); + getter_ = + create_edge_property_path_accessor(txn, name, ctx, tag, type_); + } else if (pt.has_label()) { + getter_ = create_edge_label_path_accessor(ctx, tag); + } else if (pt.has_id()) { + getter_ = create_edge_global_id_path_accessor(ctx, tag); + } else { + LOG(FATAL) << "not support..."; + } + } else { + getter_ = std::make_shared(ctx, tag); + // LOG(FATAL) << "not support for edge column - " << tag; + } + } else if (ctx.get(tag)->column_type() == ContextColumnType::kPath) { + if (pb.has_property()) { + auto& pt = pb.property(); + if (pt.has_len()) { + getter_ = std::make_shared(ctx, tag); + } else { + LOG(FATAL) << "not support for path column - " << pt.DebugString(); + } + } else { + getter_ = std::make_shared(ctx, tag); + } + } else { + LOG(FATAL) << "not support for " << ctx.get(tag)->column_info(); + } + } else { + if (var_type == VarType::kVertexVar) { + if (pb.has_property()) { + auto& pt = pb.property(); + if (pt.has_id()) { + getter_ = std::make_shared(); + } else if (pt.has_key()) { + if (pt.key().name() == "id") { + if (type_ == RTAnyType::kStringValue) { + getter_ = std::make_shared< + VertexIdVertexAccessor>(txn); + } else if (type_ == RTAnyType::kI32Value) { + getter_ = std::make_shared< + VertexIdVertexAccessor>(txn); + } else if (type_ == RTAnyType::kI64Value) { + getter_ = std::make_shared< + VertexIdVertexAccessor>(txn); + } else { + LOG(FATAL) << "not support for " + << static_cast(type_.type_enum_); + } + } else { + getter_ = create_vertex_property_vertex_accessor(txn, type_, + pt.key().name()); + } + } else if (pt.has_label()) { + getter_ = std::make_shared(); + } else { + LOG(FATAL) << "xxx, " << pt.item_case(); + } + } else { + LOG(FATAL) << "not support"; + } + } else if (var_type == VarType::kEdgeVar) { + if (pb.has_property()) { + auto& pt = pb.property(); + if (pt.has_key()) { + auto name = pt.key().name(); + getter_ = + create_edge_property_edge_accessor(txn, name, ctx, tag, type_); + } else if (pt.has_label()) { + getter_ = create_edge_label_edge_accessor(); + } else if (pt.has_id()) { + getter_ = create_edge_global_id_edge_accessor(); + } else { + LOG(FATAL) << "not support"; + } + } else { + LOG(FATAL) << "not support"; + } + } else { + LOG(FATAL) << "not support"; + } + } + } + ~Var() {} + + RTAny get(size_t path_idx) const { return getter_->eval_path(path_idx); } + RTAny get_vertex(label_t label, vid_t v, size_t idx) const { + return getter_->eval_vertex(label, v, idx); + } RTAny get_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx) const; + const Any& data, size_t idx) const { + return getter_->eval_edge(label, src, dst, data, idx); + } - RTAny get(size_t path_idx, int) const; - RTAny get_vertex(label_t label, vid_t v, size_t idx, int) const; + RTAny get(size_t path_idx, int) const { + return getter_->eval_path(path_idx, 0); + } + RTAny get_vertex(label_t label, vid_t v, size_t idx, int) const { + return getter_->eval_vertex(label, v, idx, 0); + } RTAny get_edge(const LabelTriplet& label, vid_t src, vid_t dst, - const Any& data, size_t idx, int) const; - RTAnyType type() const; + const Any& data, size_t idx, int) const { + return getter_->eval_edge(label, src, dst, data, idx, 0); + } + RTAnyType type() const { return type_; } bool is_optional() const { return getter_->is_optional(); } - std::shared_ptr builder() const; + std::shared_ptr builder() const { + return getter_->builder(); + } private: std::shared_ptr getter_; diff --git a/flex/engines/graph_db/runtime/common/accessors.cc b/flex/engines/graph_db/runtime/common/accessors.cc deleted file mode 100644 index fcec9738a4bb..000000000000 --- a/flex/engines/graph_db/runtime/common/accessors.cc +++ /dev/null @@ -1,244 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/accessors.h" -#include "flex/engines/graph_db/runtime/common/rt_any.h" - -namespace gs { - -namespace runtime { - -std::shared_ptr create_context_value_accessor(const Context& ctx, - int tag, - RTAnyType type) { - auto col = ctx.get(tag); - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>(ctx, tag); - case RTAnyType::RTAnyTypeImpl::kI32Value: - return std::make_shared>(ctx, tag); - case RTAnyType::RTAnyTypeImpl::kU64Value: - return std::make_shared>(ctx, tag); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared>(ctx, tag); - case RTAnyType::RTAnyTypeImpl::kDate32: - return std::make_shared>(ctx, tag); - case RTAnyType::RTAnyTypeImpl::kStringSetValue: - return std::make_shared>>(ctx, - tag); - case RTAnyType::RTAnyTypeImpl::kBoolValue: - return std::make_shared>(ctx, tag); - case RTAnyType::RTAnyTypeImpl::kTuple: - return std::make_shared>(ctx, tag); - case RTAnyType::RTAnyTypeImpl::kList: - return std::make_shared>(ctx, tag); - - default: - LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); - } - return nullptr; -} - -std::shared_ptr create_vertex_property_path_accessor( - const ReadTransaction& txn, const Context& ctx, int tag, RTAnyType type, - const std::string& prop_name) { - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>(txn, ctx, tag, - prop_name); - case RTAnyType::RTAnyTypeImpl::kI32Value: - return std::make_shared>(txn, ctx, tag, - prop_name); - case RTAnyType::RTAnyTypeImpl::kU64Value: - return std::make_shared>(txn, ctx, tag, - prop_name); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared>( - txn, ctx, tag, prop_name); - case RTAnyType::RTAnyTypeImpl::kDate32: - return std::make_shared>(txn, ctx, tag, - prop_name); - default: - LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); - } - return nullptr; -} - -std::shared_ptr create_vertex_label_path_accessor(const Context& ctx, - int tag) { - return std::make_shared(ctx, tag); -} - -std::shared_ptr create_vertex_property_vertex_accessor( - const ReadTransaction& txn, RTAnyType type, const std::string& prop_name) { - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>(txn, - prop_name); - case RTAnyType::RTAnyTypeImpl::kI32Value: - return std::make_shared>(txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kU64Value: - return std::make_shared>(txn, - prop_name); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared>( - txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kDate32: - return std::make_shared>(txn, prop_name); - default: - LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); - } - return nullptr; -} - -std::shared_ptr create_edge_property_path_accessor( - const ReadTransaction& txn, const std::string& name, const Context& ctx, - int tag, RTAnyType type) { - auto col = std::dynamic_pointer_cast(ctx.get(tag)); - const auto& labels = col->get_labels(); - bool multip_properties = false; - if (txn.schema().has_multi_props_edge()) { - for (auto label : labels) { - auto& properties = txn.schema().get_edge_properties( - label.src_label, label.dst_label, label.edge_label); - if (properties.size() > 1) { - multip_properties = true; - break; - } - } - } - if (multip_properties) { - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>( - txn, name, ctx, tag); - case RTAnyType::RTAnyTypeImpl::kI32Value: - return std::make_shared>( - txn, name, ctx, tag); - case RTAnyType::RTAnyTypeImpl::kU64Value: - return std::make_shared>( - txn, name, ctx, tag); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared< - MultiPropsEdgePropertyPathAccessor>(txn, name, ctx, - tag); - case RTAnyType::RTAnyTypeImpl::kDate32: - return std::make_shared>( - txn, name, ctx, tag); - case RTAnyType::RTAnyTypeImpl::kF64Value: - return std::make_shared>( - txn, name, ctx, tag); - default: - LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); - } - } else { - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>(txn, name, ctx, - tag); - case RTAnyType::RTAnyTypeImpl::kI32Value: - return std::make_shared>(txn, name, ctx, - tag); - case RTAnyType::RTAnyTypeImpl::kU64Value: - return std::make_shared>(txn, name, - ctx, tag); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared>( - txn, name, ctx, tag); - case RTAnyType::RTAnyTypeImpl::kDate32: - return std::make_shared>(txn, name, ctx, - tag); - case RTAnyType::RTAnyTypeImpl::kF64Value: - return std::make_shared>(txn, name, ctx, - tag); - default: - LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); - } - } - return nullptr; -} - -std::shared_ptr create_edge_label_path_accessor(const Context& ctx, - int tag) { - return std::make_shared(ctx, tag); -} - -std::shared_ptr create_edge_label_edge_accessor() { - return std::make_shared(); -} - -std::shared_ptr create_edge_global_id_path_accessor( - const Context& ctx, int tag) { - return std::make_shared(ctx, tag); -} - -std::shared_ptr create_edge_global_id_edge_accessor() { - return std::make_shared(); -} - -std::shared_ptr create_edge_property_edge_accessor( - const ReadTransaction& txn, const std::string& prop_name, RTAnyType type) { - bool multip_properties = txn.schema().has_multi_props_edge(); - - if (multip_properties) { - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>( - txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kI32Value: - return std::make_shared>( - txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kU64Value: - return std::make_shared>( - txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared< - MultiPropsEdgePropertyEdgeAccessor>(txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kDate32: - return std::make_shared>( - txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kF64Value: - return std::make_shared>( - txn, prop_name); - default: - LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); - } - } else { - switch (type.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return std::make_shared>(txn, - prop_name); - case RTAnyType::RTAnyTypeImpl::kI32Value: - return std::make_shared>(txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kU64Value: - return std::make_shared>(txn, - prop_name); - case RTAnyType::RTAnyTypeImpl::kStringValue: - return std::make_shared>( - txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kDate32: - return std::make_shared>(txn, prop_name); - case RTAnyType::RTAnyTypeImpl::kF64Value: - return std::make_shared>(txn, prop_name); - default: - LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); - } - } - return nullptr; -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/accessors.h b/flex/engines/graph_db/runtime/common/accessors.h index 33a468a7155d..ce1b3b1d7a1e 100644 --- a/flex/engines/graph_db/runtime/common/accessors.h +++ b/flex/engines/graph_db/runtime/common/accessors.h @@ -16,7 +16,7 @@ #ifndef RUNTIME_COMMON_ACCESSORS_H_ #define RUNTIME_COMMON_ACCESSORS_H_ -#include "flex/engines/graph_db/database/read_transaction.h" +#include "flex/engines/graph_db/runtime/adhoc/graph_interface.h" #include "flex/engines/graph_db/runtime/common/columns/edge_columns.h" #include "flex/engines/graph_db/runtime/common/columns/path_columns.h" #include "flex/engines/graph_db/runtime/common/columns/value_columns.h" @@ -93,11 +93,12 @@ class VertexPathAccessor : public IAccessor { const IVertexColumn& vertex_col_; }; -template +template class VertexIdPathAccessor : public IAccessor { public: using elem_t = KEY_T; - VertexIdPathAccessor(const ReadTransaction& txn, const Context& ctx, int tag) + VertexIdPathAccessor(const GraphInterface& txn, + const Context& ctx, int tag) : txn_(txn), vertex_col_(*std::dynamic_pointer_cast(ctx.get(tag))) {} @@ -117,7 +118,7 @@ class VertexIdPathAccessor : public IAccessor { } private: - const ReadTransaction& txn_; + const GraphInterface& txn_; const IVertexColumn& vertex_col_; }; @@ -146,19 +147,19 @@ class VertexGIdPathAccessor : public IAccessor { const IVertexColumn& vertex_col_; }; -template +template class VertexPropertyPathAccessor : public IAccessor { public: using elem_t = T; - VertexPropertyPathAccessor(const ReadTransaction& txn, const Context& ctx, - int tag, const std::string& prop_name) + VertexPropertyPathAccessor(const GraphInterface& txn, + const Context& ctx, int tag, + const std::string& prop_name) : vertex_col_(*std::dynamic_pointer_cast(ctx.get(tag))) { - int label_num = txn.schema().vertex_label_num(); - property_columns_.resize(label_num, nullptr); + int label_num = txn.VertexLabelNum(); + property_columns_.resize(label_num); for (int i = 0; i < label_num; ++i) { - property_columns_[i] = dynamic_cast*>( - txn.get_vertex_property_column(static_cast(i), prop_name) - .get()); + property_columns_[i] = + txn.template GetVertexPropertyGetter(i, prop_name); } } @@ -168,7 +169,7 @@ class VertexPropertyPathAccessor : public IAccessor { } auto label_set = vertex_col_.get_labels_set(); for (auto label : label_set) { - if (property_columns_[label] == nullptr) { + if (property_columns_[label].EmptyProperty()) { return true; } } @@ -177,12 +178,7 @@ class VertexPropertyPathAccessor : public IAccessor { elem_t typed_eval_path(size_t idx) const { const auto& v = vertex_col_.get_vertex(idx); - auto col_ptr = property_columns_[v.first]; - if (col_ptr != nullptr) { - return property_columns_[v.first]->get_view(v.second); - } else { - return elem_t(); - } + return property_columns_[v.first].get_view(v.second); } RTAny eval_path(size_t idx) const override { @@ -196,16 +192,18 @@ class VertexPropertyPathAccessor : public IAccessor { } const auto& v = vertex_col_.get_vertex(idx); auto col_ptr = property_columns_[v.first]; - if (col_ptr != nullptr) { - return TypedConverter::from_typed(col_ptr->get_view(v.second)); - } else { - return RTAny(RTAnyType::kNull); - } + return col_ptr.get_any(v.second); + // if (col_ptr != nullptr) { + // return TypedConverter::from_typed(col_ptr->get_view(v.second)); + // } else { + // return RTAny(RTAnyType::kNull); + // } } private: const IVertexColumn& vertex_col_; - std::vector*> property_columns_; + // std::vector*> property_columns_; + std::vector> property_columns_; }; class VertexLabelPathAccessor : public IAccessor { @@ -272,11 +270,11 @@ class ContextValueAccessor : public IAccessor { const IValueColumn& col_; }; -template +template class VertexIdVertexAccessor : public IAccessor { public: using elem_t = KEY_T; - VertexIdVertexAccessor(const ReadTransaction& txn) : txn_(txn) {} + VertexIdVertexAccessor(const GraphInterface& txn) : txn_(txn) {} elem_t typed_eval_vertex(label_t label, vid_t v, size_t idx) const { return AnyConverter::from_any(txn_.GetVertexId(label, v)); @@ -292,7 +290,7 @@ class VertexIdVertexAccessor : public IAccessor { } private: - const ReadTransaction& txn_; + const GraphInterface& txn_; }; class VertexGIdVertexAccessor : public IAccessor { @@ -314,26 +312,22 @@ class VertexGIdVertexAccessor : public IAccessor { } }; -template +template class VertexPropertyVertexAccessor : public IAccessor { public: using elem_t = T; - VertexPropertyVertexAccessor(const ReadTransaction& txn, + VertexPropertyVertexAccessor(const GraphInterface& txn, const std::string& prop_name) { - int label_num = txn.schema().vertex_label_num(); - property_columns_.resize(label_num, nullptr); + int label_num = txn.VertexLabelNum(); + property_columns_.resize(label_num); for (int i = 0; i < label_num; ++i) { - property_columns_[i] = dynamic_cast*>( - txn.get_vertex_property_column(static_cast(i), prop_name) - .get()); + property_columns_[i] = + txn.template GetVertexPropertyGetter(i, prop_name); } } elem_t typed_eval_vertex(label_t label, vid_t v, size_t idx) const { - if (property_columns_[label] == nullptr) { - return elem_t(); - } - return property_columns_[label]->get_view(v); + return property_columns_[label].get_view(v); } RTAny eval_path(size_t idx) const override { @@ -342,22 +336,16 @@ class VertexPropertyVertexAccessor : public IAccessor { } RTAny eval_vertex(label_t label, vid_t v, size_t idx) const override { - if (property_columns_[label] == nullptr) { - return RTAny(); - } - return TypedConverter::from_typed(property_columns_[label]->get_view(v)); + return TypedConverter::from_typed(property_columns_[label].get_view(v)); } RTAny eval_vertex(label_t label, vid_t v, size_t idx, int) const override { - if (property_columns_[label] == nullptr) { - return RTAny(RTAnyType::kNull); - } - return TypedConverter::from_typed(property_columns_[label]->get_view(v)); + return TypedConverter::from_typed(property_columns_[label].get_view(v)); } bool is_optional() const override { for (auto col : property_columns_) { - if (col == nullptr) { + if (col.EmptyProperty()) { return true; } } @@ -366,7 +354,8 @@ class VertexPropertyVertexAccessor : public IAccessor { } private: - std::vector*> property_columns_; + // std::vector*> property_columns_; + std::vector> property_columns_; }; class EdgeIdPathAccessor : public IAccessor { @@ -398,11 +387,11 @@ class EdgeIdPathAccessor : public IAccessor { const IEdgeColumn& edge_col_; }; -template +template class EdgePropertyPathAccessor : public IAccessor { public: using elem_t = T; - EdgePropertyPathAccessor(const ReadTransaction& txn, + EdgePropertyPathAccessor(const GraphInterface& txn, const std::string& prop_name, const Context& ctx, int tag) : col_(*std::dynamic_pointer_cast(ctx.get(tag))) {} @@ -436,27 +425,27 @@ class EdgePropertyPathAccessor : public IAccessor { const IEdgeColumn& col_; }; -template +template class MultiPropsEdgePropertyPathAccessor : public IAccessor { public: using elem_t = T; - MultiPropsEdgePropertyPathAccessor(const ReadTransaction& txn, + MultiPropsEdgePropertyPathAccessor(const GraphInterface& txn, const std::string& prop_name, const Context& ctx, int tag) : col_(*std::dynamic_pointer_cast(ctx.get(tag))) { - const auto& labels = col_.get_labels(); - vertex_label_num_ = txn.schema().vertex_label_num(); - edge_label_num_ = txn.schema().edge_label_num(); + auto labels = col_.get_labels(); + vertex_label_num_ = txn.VertexLabelNum(); + edge_label_num_ = txn.EdgeLabelNum(); prop_index_.resize( 2 * vertex_label_num_ * vertex_label_num_ * edge_label_num_, std::numeric_limits::max()); for (auto& label : labels) { size_t idx = label.src_label * vertex_label_num_ * edge_label_num_ + label.dst_label * edge_label_num_ + label.edge_label; - const auto& names = txn.schema().get_edge_property_names( + const auto& edge_property_names = txn.GetEdgePropertyNames( label.src_label, label.dst_label, label.edge_label); - for (size_t i = 0; i < names.size(); ++i) { - if (names[i] == prop_name) { + for (size_t i = 0; i < edge_property_names.size(); ++i) { + if (edge_property_names[i] == prop_name) { prop_index_[idx] = i; break; } @@ -569,11 +558,11 @@ class EdgeLabelEdgeAccessor : public IAccessor { } }; -template +template class EdgePropertyEdgeAccessor : public IAccessor { public: using elem_t = T; - EdgePropertyEdgeAccessor(const ReadTransaction& txn, + EdgePropertyEdgeAccessor(const GraphInterface& txn, const std::string& name) {} elem_t typed_eval_edge(const LabelTriplet& label, vid_t src, vid_t dst, @@ -684,33 +673,32 @@ class EdgeGlobalIdEdgeAccessor : public IAccessor { } }; -template +template class MultiPropsEdgePropertyEdgeAccessor : public IAccessor { public: using elem_t = T; - MultiPropsEdgePropertyEdgeAccessor(const ReadTransaction& txn, + MultiPropsEdgePropertyEdgeAccessor(const GraphInterface& txn, const std::string& name) { - edge_label_num_ = txn.schema().edge_label_num(); - vertex_label_num_ = txn.schema().vertex_label_num(); + edge_label_num_ = txn.EdgeLabelNum(); + vertex_label_num_ = txn.VertexLabelNum(); indexs.resize(2 * vertex_label_num_ * vertex_label_num_ * edge_label_num_, std::numeric_limits::max()); for (label_t src_label = 0; src_label < vertex_label_num_; ++src_label) { - auto src = txn.schema().get_vertex_label_name(src_label); + auto src = txn.GetVertexLabelName(src_label); for (label_t dst_label = 0; dst_label < vertex_label_num_; ++dst_label) { - auto dst = txn.schema().get_vertex_label_name(dst_label); + auto dst = txn.GetVertexLabelName(dst_label); for (label_t edge_label = 0; edge_label < edge_label_num_; ++edge_label) { - auto edge = txn.schema().get_edge_label_name(edge_label); - if (!txn.schema().exist(src, dst, edge)) { + auto edge = txn.GetEdgeLabelName(edge_label); + if (!txn.ExistEdgeTriplet(src_label, dst_label, edge_label)) { continue; } size_t idx = src_label * vertex_label_num_ * edge_label_num_ + dst_label * edge_label_num_ + edge_label; - const std::vector& names = - txn.schema().get_edge_property_names(src_label, dst_label, - edge_label); - for (size_t i = 0; i < names.size(); ++i) { - if (names[i] == name) { + const auto& properties = + txn.GetEdgePropertyNames(src_label, dst_label, edge_label); + for (size_t i = 0; i < properties.size(); ++i) { + if (properties[i] == name) { indexs[idx] = i; break; } @@ -858,20 +846,19 @@ std::shared_ptr create_context_value_accessor(const Context& ctx, int tag, RTAnyType type); +template std::shared_ptr create_vertex_property_path_accessor( - const ReadTransaction& txn, const Context& ctx, int tag, RTAnyType type, - const std::string& prop_name); + const GraphInterface& txn, const Context& ctx, int tag, + RTAnyType type, const std::string& prop_name); +template std::shared_ptr create_vertex_property_vertex_accessor( - const ReadTransaction& txn, RTAnyType type, const std::string& prop_name); + const GraphInterface& txn, RTAnyType type, + const std::string& prop_name); std::shared_ptr create_vertex_label_path_accessor(const Context& ctx, int tag); -std::shared_ptr create_edge_property_path_accessor( - const ReadTransaction& txn, const std::string& prop_name, - const Context& ctx, int tag, RTAnyType type); - std::shared_ptr create_edge_label_path_accessor(const Context& ctx, int tag); @@ -882,8 +869,229 @@ std::shared_ptr create_edge_global_id_path_accessor( std::shared_ptr create_edge_global_id_edge_accessor(); +std::shared_ptr create_context_value_accessor(const Context& ctx, + int tag, + RTAnyType type) { + auto col = ctx.get(tag); + switch (type.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return std::make_shared>(ctx, tag); + case RTAnyType::RTAnyTypeImpl::kI32Value: + return std::make_shared>(ctx, tag); + case RTAnyType::RTAnyTypeImpl::kU64Value: + return std::make_shared>(ctx, tag); + case RTAnyType::RTAnyTypeImpl::kStringValue: + return std::make_shared>(ctx, tag); + case RTAnyType::RTAnyTypeImpl::kDate32: + return std::make_shared>(ctx, tag); + case RTAnyType::RTAnyTypeImpl::kStringSetValue: + return std::make_shared>>(ctx, + tag); + case RTAnyType::RTAnyTypeImpl::kBoolValue: + return std::make_shared>(ctx, tag); + case RTAnyType::RTAnyTypeImpl::kTuple: + return std::make_shared>(ctx, tag); + case RTAnyType::RTAnyTypeImpl::kList: + return std::make_shared>(ctx, tag); + + default: + LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); + } + return nullptr; +} + +template +std::shared_ptr create_vertex_property_path_accessor( + const GraphInterface& txn, const Context& ctx, int tag, + RTAnyType type, const std::string& prop_name) { + switch (type.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return std::make_shared>( + txn, ctx, tag, prop_name); + case RTAnyType::RTAnyTypeImpl::kI32Value: + return std::make_shared>( + txn, ctx, tag, prop_name); + case RTAnyType::RTAnyTypeImpl::kU64Value: + return std::make_shared>( + txn, ctx, tag, prop_name); + case RTAnyType::RTAnyTypeImpl::kStringValue: + return std::make_shared< + VertexPropertyPathAccessor>(txn, ctx, tag, + prop_name); + case RTAnyType::RTAnyTypeImpl::kDate32: + return std::make_shared>( + txn, ctx, tag, prop_name); + default: + LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); + } + return nullptr; +} + +std::shared_ptr create_vertex_label_path_accessor(const Context& ctx, + int tag) { + return std::make_shared(ctx, tag); +} + +template +std::shared_ptr create_vertex_property_vertex_accessor( + const GraphInterface& txn, RTAnyType type, + const std::string& prop_name) { + switch (type.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return std::make_shared>( + txn, prop_name); + case RTAnyType::RTAnyTypeImpl::kI32Value: + return std::make_shared>( + txn, prop_name); + case RTAnyType::RTAnyTypeImpl::kU64Value: + return std::make_shared>( + txn, prop_name); + case RTAnyType::RTAnyTypeImpl::kStringValue: + return std::make_shared< + VertexPropertyVertexAccessor>(txn, + prop_name); + case RTAnyType::RTAnyTypeImpl::kDate32: + return std::make_shared>( + txn, prop_name); + default: + LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); + } + return nullptr; +} + +template +bool check_whether_multiple_properties( + const GraphInterface& txn, + const std::vector& labels) { + bool multiple_properties = false; + for (auto label : labels) { + const auto& properties = txn.GetEdgePropertyNames( + label.src_label, label.dst_label, label.edge_label); + if (properties.size() > 1) { + multiple_properties = true; + break; + } + } + return multiple_properties; +} + +template +std::shared_ptr create_edge_property_path_accessor( + const GraphInterface& txn, const std::string& name, + const Context& ctx, int tag, RTAnyType type) { + auto col = std::dynamic_pointer_cast(ctx.get(tag)); + auto labels = col->get_labels(); + auto multiple_properties = check_whether_multiple_properties(txn, labels); + + if (multiple_properties) { + switch (type.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return std::make_shared< + MultiPropsEdgePropertyPathAccessor>(txn, name, + ctx, tag); + case RTAnyType::RTAnyTypeImpl::kI32Value: + return std::make_shared< + MultiPropsEdgePropertyPathAccessor>(txn, name, ctx, + tag); + case RTAnyType::RTAnyTypeImpl::kU64Value: + return std::make_shared< + MultiPropsEdgePropertyPathAccessor>(txn, name, + ctx, tag); + case RTAnyType::RTAnyTypeImpl::kStringValue: + return std::make_shared< + MultiPropsEdgePropertyPathAccessor>( + txn, name, ctx, tag); + case RTAnyType::RTAnyTypeImpl::kDate32: + return std::make_shared< + MultiPropsEdgePropertyPathAccessor>(txn, name, ctx, + tag); + case RTAnyType::RTAnyTypeImpl::kF64Value: + return std::make_shared< + MultiPropsEdgePropertyPathAccessor>(txn, name, + ctx, tag); + default: + LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); + } + } else { + switch (type.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return std::make_shared>( + txn, name, ctx, tag); + case RTAnyType::RTAnyTypeImpl::kI32Value: + return std::make_shared>( + txn, name, ctx, tag); + case RTAnyType::RTAnyTypeImpl::kU64Value: + return std::make_shared>( + txn, name, ctx, tag); + case RTAnyType::RTAnyTypeImpl::kStringValue: + return std::make_shared< + EdgePropertyPathAccessor>(txn, name, + ctx, tag); + case RTAnyType::RTAnyTypeImpl::kDate32: + return std::make_shared>( + txn, name, ctx, tag); + case RTAnyType::RTAnyTypeImpl::kF64Value: + return std::make_shared>( + txn, name, ctx, tag); + default: + LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); + } + } + return nullptr; +} + +std::shared_ptr create_edge_label_path_accessor(const Context& ctx, + int tag) { + return std::make_shared(ctx, tag); +} + +std::shared_ptr create_edge_label_edge_accessor() { + return std::make_shared(); +} + +std::shared_ptr create_edge_global_id_path_accessor( + const Context& ctx, int tag) { + return std::make_shared(ctx, tag); +} + +std::shared_ptr create_edge_global_id_edge_accessor() { + return std::make_shared(); +} + +template std::shared_ptr create_edge_property_edge_accessor( - const ReadTransaction& txn, const std::string& prop_name, RTAnyType type); + const GraphInterface& txn, const std::string& prop_name, + const Context& ctx, int tag, RTAnyType type) { + // TODO(zhanglei,lexiao): Can we just return + // MultiPropsEdgePropertyEdgeAccessor here? + switch (type.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return std::make_shared< + MultiPropsEdgePropertyEdgeAccessor>(txn, + prop_name); + case RTAnyType::RTAnyTypeImpl::kI32Value: + return std::make_shared< + MultiPropsEdgePropertyEdgeAccessor>(txn, prop_name); + case RTAnyType::RTAnyTypeImpl::kU64Value: + return std::make_shared< + MultiPropsEdgePropertyEdgeAccessor>(txn, + prop_name); + case RTAnyType::RTAnyTypeImpl::kStringValue: + return std::make_shared< + MultiPropsEdgePropertyEdgeAccessor>( + txn, prop_name); + case RTAnyType::RTAnyTypeImpl::kDate32: + return std::make_shared< + MultiPropsEdgePropertyEdgeAccessor>(txn, prop_name); + case RTAnyType::RTAnyTypeImpl::kF64Value: + return std::make_shared< + MultiPropsEdgePropertyEdgeAccessor>(txn, prop_name); + default: + LOG(FATAL) << "not implemented - " << static_cast(type.type_enum_); + } + + return nullptr; +} } // namespace runtime diff --git a/flex/engines/graph_db/runtime/common/columns/edge_columns.cc b/flex/engines/graph_db/runtime/common/columns/edge_columns.cc deleted file mode 100644 index 35d0acce0e84..000000000000 --- a/flex/engines/graph_db/runtime/common/columns/edge_columns.cc +++ /dev/null @@ -1,247 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/columns/edge_columns.h" - -namespace gs { - -namespace runtime { - -std::shared_ptr SDSLEdgeColumn::dup() const { - std::vector sub_types; - if (prop_type_ == PropertyType::kRecordView) { - sub_types = std::dynamic_pointer_cast>(prop_col_) - ->sub_types(); - } - SDSLEdgeColumnBuilder builder(dir_, label_, prop_type_, sub_types); - builder.reserve(edges_.size()); - for (size_t i = 0; i < edges_.size(); ++i) { - auto e = get_edge(i); - builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e)); - } - return builder.finish(); -} - -std::shared_ptr SDSLEdgeColumn::shuffle( - const std::vector& offsets) const { - std::vector sub_types; - if (prop_type_ == PropertyType::kRecordView) { - sub_types = std::dynamic_pointer_cast>(prop_col_) - ->sub_types(); - } - SDSLEdgeColumnBuilder builder(dir_, label_, prop_type_, sub_types); - size_t new_row_num = offsets.size(); - builder.reserve(new_row_num); - - if (prop_type_ == PropertyType::kEmpty) { - for (auto off : offsets) { - const auto& e = edges_[off]; - - builder.push_back_endpoints(e.first, e.second); - } - } else { - auto& ret_props = *builder.prop_col_; - ret_props.resize(new_row_num); - for (size_t idx = 0; idx < new_row_num; ++idx) { - size_t off = offsets[idx]; - const auto& e = edges_[off]; - builder.push_back_endpoints(e.first, e.second); - ret_props.set_any(idx, prop_col_->get(off)); - } - } - - return builder.finish(); -} - -std::shared_ptr SDSLEdgeColumnBuilder::finish() { - auto ret = - std::make_shared(dir_, label_, prop_type_, sub_types_); - ret->edges_.swap(edges_); - // shrink to fit - prop_col_->resize(edges_.size()); - ret->prop_col_ = prop_col_; - return ret; -} - -std::shared_ptr BDSLEdgeColumn::dup() const { - BDSLEdgeColumnBuilder builder(label_, prop_type_); - builder.reserve(size()); - for (size_t i = 0; i < size(); ++i) { - auto e = get_edge(i); - builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e), - std::get<4>(e)); - } - return builder.finish(); -} - -std::shared_ptr BDSLEdgeColumn::shuffle( - const std::vector& offsets) const { - BDSLEdgeColumnBuilder builder(label_, prop_type_); - size_t new_row_num = offsets.size(); - builder.reserve(new_row_num); - - auto& ret_props = *builder.prop_col_; - ret_props.resize(new_row_num); - for (size_t idx = 0; idx < new_row_num; ++idx) { - size_t off = offsets[idx]; - const auto& e = edges_[off]; - builder.push_back_endpoints(std::get<0>(e), std::get<1>(e), std::get<2>(e)); - ret_props.set_any(idx, prop_col_->get(off)); - } - - return builder.finish(); -} - -std::shared_ptr BDSLEdgeColumnBuilder::finish() { - auto ret = std::make_shared(label_, prop_type_); - ret->edges_.swap(edges_); - ret->prop_col_ = prop_col_; - return ret; -} - -std::shared_ptr SDMLEdgeColumn::dup() const { - SDMLEdgeColumnBuilder builder(dir_, edge_labels_); - builder.reserve(edges_.size()); - for (auto& e : edges_) { - auto idx = std::get<0>(e); - builder.push_back_opt(idx, std::get<1>(e), std::get<2>(e), - prop_cols_[idx]->get(std::get<3>(e))); - } - return builder.finish(); -} - -std::shared_ptr SDMLEdgeColumn::shuffle( - const std::vector& offsets) const { - SDMLEdgeColumnBuilder builder(dir_, edge_labels_); - size_t new_row_num = offsets.size(); - builder.reserve(new_row_num); - for (size_t idx = 0; idx < new_row_num; ++idx) { - size_t off = offsets[idx]; - const auto& e = edges_[off]; - auto index = std::get<0>(e); - auto offset = std::get<3>(e); - builder.push_back_opt(index, std::get<1>(e), std::get<2>(e), - prop_cols_[index]->get(offset)); - } - return builder.finish(); -} - -std::shared_ptr SDMLEdgeColumnBuilder::finish() { - auto ret = std::make_shared(dir_, edge_labels_); - ret->edges_.swap(edges_); - ret->prop_cols_.swap(prop_cols_); - return ret; -} - -std::shared_ptr BDMLEdgeColumn::dup() const { - BDMLEdgeColumnBuilder builder(labels_); - builder.reserve(edges_.size()); - for (auto& e : edges_) { - auto idx = std::get<0>(e); - auto dir = std::get<4>(e) ? Direction::kOut : Direction::kIn; - builder.push_back_opt(idx, std::get<1>(e), std::get<2>(e), - prop_cols_[idx]->get(std::get<3>(e)), dir); - } - return builder.finish(); -} - -std::shared_ptr BDMLEdgeColumn::shuffle( - const std::vector& offsets) const { - BDMLEdgeColumnBuilder builder(labels_); - size_t new_row_num = offsets.size(); - builder.reserve(new_row_num); - for (size_t idx = 0; idx < new_row_num; ++idx) { - size_t off = offsets[idx]; - const auto& e = edges_[off]; - auto index = std::get<0>(e); - auto offset = std::get<3>(e); - auto dir = std::get<4>(e) ? Direction::kOut : Direction::kIn; - builder.push_back_opt(index, std::get<1>(e), std::get<2>(e), - prop_cols_[index]->get(offset), dir); - } - return builder.finish(); -} - -std::shared_ptr BDMLEdgeColumnBuilder::finish() { - auto ret = std::make_shared(labels_); - ret->edges_.swap(edges_); - ret->prop_cols_.swap(prop_cols_); - return ret; -} - -std::shared_ptr OptionalBDSLEdgeColumn::shuffle( - const std::vector& offsets) const { - OptionalBDSLEdgeColumnBuilder builder(label_, prop_type_); - size_t new_row_num = offsets.size(); - builder.reserve(new_row_num); - for (size_t idx = 0; idx < new_row_num; ++idx) { - size_t off = offsets[idx]; - const auto& e = get_edge(off); - builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e), - std::get<4>(e)); - } - return builder.finish(); -} -std::shared_ptr OptionalBDSLEdgeColumn::dup() const { - OptionalBDSLEdgeColumnBuilder builder(label_, prop_type_); - builder.reserve(edges_.size()); - for (size_t i = 0; i < edges_.size(); ++i) { - auto e = get_edge(i); - builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e), - std::get<4>(e)); - } - return builder.finish(); -} - -std::shared_ptr OptionalBDSLEdgeColumnBuilder::finish() { - auto ret = std::make_shared(label_, prop_type_); - ret->edges_.swap(edges_); - ret->prop_col_ = prop_col_; - return ret; -} - -std::shared_ptr OptionalSDSLEdgeColumn::shuffle( - const std::vector& offsets) const { - OptionalSDSLEdgeColumnBuilder builder(dir_, label_, prop_type_); - size_t new_row_num = offsets.size(); - builder.reserve(new_row_num); - for (size_t idx = 0; idx < new_row_num; ++idx) { - size_t off = offsets[idx]; - const auto& e = get_edge(off); - builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e)); - } - return builder.finish(); -} - -std::shared_ptr OptionalSDSLEdgeColumn::dup() const { - OptionalSDSLEdgeColumnBuilder builder(dir_, label_, prop_type_); - builder.reserve(edges_.size()); - for (size_t i = 0; i < edges_.size(); ++i) { - auto e = get_edge(i); - builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e)); - } - return builder.finish(); -} - -std::shared_ptr OptionalSDSLEdgeColumnBuilder::finish() { - auto ret = std::make_shared(dir_, label_, prop_type_); - ret->edges_.swap(edges_); - ret->prop_col_ = prop_col_; - return ret; -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/columns/edge_columns.h b/flex/engines/graph_db/runtime/common/columns/edge_columns.h index 474ffaf9d7b9..b84690fe1778 100644 --- a/flex/engines/graph_db/runtime/common/columns/edge_columns.h +++ b/flex/engines/graph_db/runtime/common/columns/edge_columns.h @@ -885,6 +885,229 @@ class OptionalBDSLEdgeColumnBuilder : public IOptionalContextColumnBuilder { std::shared_ptr prop_col_; }; +std::shared_ptr SDSLEdgeColumn::dup() const { + std::vector sub_types; + if (prop_type_ == PropertyType::kRecordView) { + sub_types = std::dynamic_pointer_cast>(prop_col_) + ->sub_types(); + } + SDSLEdgeColumnBuilder builder(dir_, label_, prop_type_, sub_types); + builder.reserve(edges_.size()); + for (size_t i = 0; i < edges_.size(); ++i) { + auto e = get_edge(i); + builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e)); + } + return builder.finish(); +} + +std::shared_ptr SDSLEdgeColumn::shuffle( + const std::vector& offsets) const { + std::vector sub_types; + if (prop_type_ == PropertyType::kRecordView) { + sub_types = std::dynamic_pointer_cast>(prop_col_) + ->sub_types(); + } + SDSLEdgeColumnBuilder builder(dir_, label_, prop_type_, sub_types); + size_t new_row_num = offsets.size(); + builder.reserve(new_row_num); + + if (prop_type_ == PropertyType::kEmpty) { + for (auto off : offsets) { + const auto& e = edges_[off]; + + builder.push_back_endpoints(e.first, e.second); + } + } else { + auto& ret_props = *builder.prop_col_; + ret_props.resize(new_row_num); + for (size_t idx = 0; idx < new_row_num; ++idx) { + size_t off = offsets[idx]; + const auto& e = edges_[off]; + builder.push_back_endpoints(e.first, e.second); + ret_props.set_any(idx, prop_col_->get(off)); + } + } + + return builder.finish(); +} + +std::shared_ptr SDSLEdgeColumnBuilder::finish() { + auto ret = + std::make_shared(dir_, label_, prop_type_, sub_types_); + ret->edges_.swap(edges_); + // shrink to fit + prop_col_->resize(edges_.size()); + ret->prop_col_ = prop_col_; + return ret; +} + +std::shared_ptr BDSLEdgeColumn::dup() const { + BDSLEdgeColumnBuilder builder(label_, prop_type_); + builder.reserve(size()); + for (size_t i = 0; i < size(); ++i) { + auto e = get_edge(i); + builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e), + std::get<4>(e)); + } + return builder.finish(); +} + +std::shared_ptr BDSLEdgeColumn::shuffle( + const std::vector& offsets) const { + BDSLEdgeColumnBuilder builder(label_, prop_type_); + size_t new_row_num = offsets.size(); + builder.reserve(new_row_num); + + auto& ret_props = *builder.prop_col_; + ret_props.resize(new_row_num); + for (size_t idx = 0; idx < new_row_num; ++idx) { + size_t off = offsets[idx]; + const auto& e = edges_[off]; + builder.push_back_endpoints(std::get<0>(e), std::get<1>(e), std::get<2>(e)); + ret_props.set_any(idx, prop_col_->get(off)); + } + + return builder.finish(); +} + +std::shared_ptr BDSLEdgeColumnBuilder::finish() { + auto ret = std::make_shared(label_, prop_type_); + ret->edges_.swap(edges_); + ret->prop_col_ = prop_col_; + return ret; +} + +std::shared_ptr SDMLEdgeColumn::dup() const { + SDMLEdgeColumnBuilder builder(dir_, edge_labels_); + builder.reserve(edges_.size()); + for (auto& e : edges_) { + auto idx = std::get<0>(e); + builder.push_back_opt(idx, std::get<1>(e), std::get<2>(e), + prop_cols_[idx]->get(std::get<3>(e))); + } + return builder.finish(); +} + +std::shared_ptr SDMLEdgeColumn::shuffle( + const std::vector& offsets) const { + SDMLEdgeColumnBuilder builder(dir_, edge_labels_); + size_t new_row_num = offsets.size(); + builder.reserve(new_row_num); + for (size_t idx = 0; idx < new_row_num; ++idx) { + size_t off = offsets[idx]; + const auto& e = edges_[off]; + auto index = std::get<0>(e); + auto offset = std::get<3>(e); + builder.push_back_opt(index, std::get<1>(e), std::get<2>(e), + prop_cols_[index]->get(offset)); + } + return builder.finish(); +} + +std::shared_ptr SDMLEdgeColumnBuilder::finish() { + auto ret = std::make_shared(dir_, edge_labels_); + ret->edges_.swap(edges_); + ret->prop_cols_.swap(prop_cols_); + return ret; +} + +std::shared_ptr BDMLEdgeColumn::dup() const { + BDMLEdgeColumnBuilder builder(labels_); + builder.reserve(edges_.size()); + for (auto& e : edges_) { + auto idx = std::get<0>(e); + auto dir = std::get<4>(e) ? Direction::kOut : Direction::kIn; + builder.push_back_opt(idx, std::get<1>(e), std::get<2>(e), + prop_cols_[idx]->get(std::get<3>(e)), dir); + } + return builder.finish(); +} + +std::shared_ptr BDMLEdgeColumn::shuffle( + const std::vector& offsets) const { + BDMLEdgeColumnBuilder builder(labels_); + size_t new_row_num = offsets.size(); + builder.reserve(new_row_num); + for (size_t idx = 0; idx < new_row_num; ++idx) { + size_t off = offsets[idx]; + const auto& e = edges_[off]; + auto index = std::get<0>(e); + auto offset = std::get<3>(e); + auto dir = std::get<4>(e) ? Direction::kOut : Direction::kIn; + builder.push_back_opt(index, std::get<1>(e), std::get<2>(e), + prop_cols_[index]->get(offset), dir); + } + return builder.finish(); +} + +std::shared_ptr BDMLEdgeColumnBuilder::finish() { + auto ret = std::make_shared(labels_); + ret->edges_.swap(edges_); + ret->prop_cols_.swap(prop_cols_); + return ret; +} + +std::shared_ptr OptionalBDSLEdgeColumn::shuffle( + const std::vector& offsets) const { + OptionalBDSLEdgeColumnBuilder builder(label_, prop_type_); + size_t new_row_num = offsets.size(); + builder.reserve(new_row_num); + for (size_t idx = 0; idx < new_row_num; ++idx) { + size_t off = offsets[idx]; + const auto& e = get_edge(off); + builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e), + std::get<4>(e)); + } + return builder.finish(); +} +std::shared_ptr OptionalBDSLEdgeColumn::dup() const { + OptionalBDSLEdgeColumnBuilder builder(label_, prop_type_); + builder.reserve(edges_.size()); + for (size_t i = 0; i < edges_.size(); ++i) { + auto e = get_edge(i); + builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e), + std::get<4>(e)); + } + return builder.finish(); +} + +std::shared_ptr OptionalBDSLEdgeColumnBuilder::finish() { + auto ret = std::make_shared(label_, prop_type_); + ret->edges_.swap(edges_); + ret->prop_col_ = prop_col_; + return ret; +} + +std::shared_ptr OptionalSDSLEdgeColumn::shuffle( + const std::vector& offsets) const { + OptionalSDSLEdgeColumnBuilder builder(dir_, label_, prop_type_); + size_t new_row_num = offsets.size(); + builder.reserve(new_row_num); + for (size_t idx = 0; idx < new_row_num; ++idx) { + size_t off = offsets[idx]; + const auto& e = get_edge(off); + builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e)); + } + return builder.finish(); +} + +std::shared_ptr OptionalSDSLEdgeColumn::dup() const { + OptionalSDSLEdgeColumnBuilder builder(dir_, label_, prop_type_); + builder.reserve(edges_.size()); + for (size_t i = 0; i < edges_.size(); ++i) { + auto e = get_edge(i); + builder.push_back_opt(std::get<1>(e), std::get<2>(e), std::get<3>(e)); + } + return builder.finish(); +} + +std::shared_ptr OptionalSDSLEdgeColumnBuilder::finish() { + auto ret = std::make_shared(dir_, label_, prop_type_); + ret->edges_.swap(edges_); + ret->prop_col_ = prop_col_; + return ret; +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/columns/path_columns.cc b/flex/engines/graph_db/runtime/common/columns/path_columns.cc deleted file mode 100644 index 51618cd19e37..000000000000 --- a/flex/engines/graph_db/runtime/common/columns/path_columns.cc +++ /dev/null @@ -1,46 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/columns/path_columns.h" - -namespace gs { -namespace runtime { -std::shared_ptr GeneralPathColumn::dup() const { - GeneralPathColumnBuilder builder; - for (const auto& path : data_) { - builder.push_back_opt(path); - } - builder.set_path_impls(path_impls_); - return builder.finish(); -} - -std::shared_ptr GeneralPathColumn::shuffle( - const std::vector& offsets) const { - GeneralPathColumnBuilder builder; - builder.reserve(offsets.size()); - for (auto& offset : offsets) { - builder.push_back_opt(data_[offset]); - } - builder.set_path_impls(path_impls_); - return builder.finish(); -} -std::shared_ptr GeneralPathColumn::builder() const { - auto builder = std::make_shared(); - builder->set_path_impls(path_impls_); - return std::dynamic_pointer_cast(builder); -} - -} // namespace runtime -} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/common/columns/path_columns.h b/flex/engines/graph_db/runtime/common/columns/path_columns.h index 136febb6d152..1b151c75e5cc 100644 --- a/flex/engines/graph_db/runtime/common/columns/path_columns.h +++ b/flex/engines/graph_db/runtime/common/columns/path_columns.h @@ -129,6 +129,31 @@ class GeneralPathColumnBuilder : public IContextColumnBuilder { std::vector> path_impls_; }; +std::shared_ptr GeneralPathColumn::dup() const { + GeneralPathColumnBuilder builder; + for (const auto& path : data_) { + builder.push_back_opt(path); + } + builder.set_path_impls(path_impls_); + return builder.finish(); +} + +std::shared_ptr GeneralPathColumn::shuffle( + const std::vector& offsets) const { + GeneralPathColumnBuilder builder; + builder.reserve(offsets.size()); + for (auto& offset : offsets) { + builder.push_back_opt(data_[offset]); + } + builder.set_path_impls(path_impls_); + return builder.finish(); +} +std::shared_ptr GeneralPathColumn::builder() const { + auto builder = std::make_shared(); + builder->set_path_impls(path_impls_); + return std::dynamic_pointer_cast(builder); +} + } // namespace runtime } // namespace gs #endif // RUNTIME_COMMON_COLUMNS_PATH_COLUMNS_H_ \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/common/columns/value_columns.cc b/flex/engines/graph_db/runtime/common/columns/value_columns.cc deleted file mode 100644 index 8a1c23ac8dfc..000000000000 --- a/flex/engines/graph_db/runtime/common/columns/value_columns.cc +++ /dev/null @@ -1,90 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/columns/value_columns.h" - -namespace gs { - -namespace runtime { - -std::shared_ptr ValueColumn::shuffle( - const std::vector& offsets) const { - ValueColumnBuilder builder; - builder.reserve(offsets.size()); - for (auto offset : offsets) { - builder.push_back_opt(data_[offset]); - } - return builder.finish(); -} - -std::shared_ptr ValueColumn::dup() const { - ValueColumnBuilder builder; - for (auto v : data_) { - builder.push_back_opt(v); - } - return builder.finish(); -} - -std::shared_ptr OptionalValueColumn::shuffle( - const std::vector& offsets) const { - OptionalValueColumnBuilder builder; - for (size_t i : offsets) { - builder.push_back_opt(data_[i], valid_[i]); - } - return builder.finish(); -} - -std::shared_ptr OptionalValueColumn::dup() - const { - OptionalValueColumnBuilder builder; - for (size_t i = 0; i < data_.size(); ++i) { - builder.push_back_opt(data_[i], valid_[i]); - } - return builder.finish(); -} - -std::shared_ptr MapValueColumn::dup() const { - MapValueColumnBuilder builder; - builder.set_keys(keys_); - for (const auto& values : values_) { - builder.push_back_opt(values); - } - return builder.finish(); -} - -std::shared_ptr MapValueColumn::shuffle( - const std::vector& offsets) const { - MapValueColumnBuilder builder; - builder.reserve(offsets.size()); - builder.set_keys(keys_); - for (auto offset : offsets) { - builder.push_back_opt(values_[offset]); - } - return builder.finish(); -} - -std::shared_ptr MapValueColumn::builder() const { - auto builder = std::make_shared(); - builder->set_keys(keys_); - return builder; -} - -template class ValueColumn; -template class ValueColumn>; -template class ValueColumn>; - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/columns/value_columns.h b/flex/engines/graph_db/runtime/common/columns/value_columns.h index 1547ab7b91fb..bd0243b05091 100644 --- a/flex/engines/graph_db/runtime/common/columns/value_columns.h +++ b/flex/engines/graph_db/runtime/common/columns/value_columns.h @@ -668,6 +668,70 @@ std::shared_ptr ValueColumn::union_col( return builder.finish(); } +std::shared_ptr ValueColumn::shuffle( + const std::vector& offsets) const { + ValueColumnBuilder builder; + builder.reserve(offsets.size()); + for (auto offset : offsets) { + builder.push_back_opt(data_[offset]); + } + return builder.finish(); +} + +std::shared_ptr ValueColumn::dup() const { + ValueColumnBuilder builder; + for (auto v : data_) { + builder.push_back_opt(v); + } + return builder.finish(); +} + +std::shared_ptr OptionalValueColumn::shuffle( + const std::vector& offsets) const { + OptionalValueColumnBuilder builder; + for (size_t i : offsets) { + builder.push_back_opt(data_[i], valid_[i]); + } + return builder.finish(); +} + +std::shared_ptr OptionalValueColumn::dup() const { + OptionalValueColumnBuilder builder; + for (size_t i = 0; i < data_.size(); ++i) { + builder.push_back_opt(data_[i], valid_[i]); + } + return builder.finish(); +} + +std::shared_ptr MapValueColumn::dup() const { + MapValueColumnBuilder builder; + builder.set_keys(keys_); + for (const auto& values : values_) { + builder.push_back_opt(values); + } + return builder.finish(); +} + +std::shared_ptr MapValueColumn::shuffle(const std::vector& offsets) const { + MapValueColumnBuilder builder; + builder.reserve(offsets.size()); + builder.set_keys(keys_); + for (auto offset : offsets) { + builder.push_back_opt(values_[offset]); + } + return builder.finish(); +} + +std::shared_ptr MapValueColumn::builder() const { + auto builder = std::make_shared(); + builder->set_keys(keys_); + return builder; +} + +template class ValueColumn; +template class ValueColumn>; +template class ValueColumn>; + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/columns/vertex_columns.cc b/flex/engines/graph_db/runtime/common/columns/vertex_columns.cc deleted file mode 100644 index 426e98974a40..000000000000 --- a/flex/engines/graph_db/runtime/common/columns/vertex_columns.cc +++ /dev/null @@ -1,249 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/columns/vertex_columns.h" - -namespace gs { -namespace runtime { - -std::shared_ptr SLVertexColumn::shuffle( - const std::vector& offsets) const { - SLVertexColumnBuilder builder(label_); - builder.reserve(offsets.size()); - for (auto offset : offsets) { - builder.push_back_opt(vertices_[offset]); - } - return builder.finish(); -} - -void SLVertexColumn::generate_dedup_offset(std::vector& offsets) const { - offsets.clear(); -#if 0 - std::set vset; - size_t n = vertices_.size(); - for (size_t i = 0; i != n; ++i) { - vid_t cur = vertices_[i]; - if (vset.find(cur) == vset.end()) { - offsets.push_back(i); - vset.insert(cur); - } - } -#else - std::vector bitset; - size_t vnum = vertices_.size(); - bitset.resize(vnum); - for (size_t i = 0; i < vnum; ++i) { - vid_t v = vertices_[i]; - if (bitset.size() <= v) { - bitset.resize(v + 1); - bitset[v] = true; - - offsets.push_back(i); - } else { - if (!bitset[v]) { - offsets.push_back(i); - bitset[v] = true; - } - } - } -#endif -} - -std::shared_ptr SLVertexColumn::union_col( - std::shared_ptr other) const { - CHECK(other->column_type() == ContextColumnType::kVertex); - const IVertexColumn& vertex_column = - *std::dynamic_pointer_cast(other); - if (vertex_column.vertex_column_type() == VertexColumnType::kSingle) { - const SLVertexColumn& col = - dynamic_cast(vertex_column); - if (label() == col.label()) { - SLVertexColumnBuilder builder(label()); - for (auto v : vertices_) { - builder.push_back_opt(v); - } - for (auto v : col.vertices_) { - builder.push_back_opt(v); - } - return builder.finish(); - } - } - LOG(FATAL) << "not support..."; - return nullptr; -} - -std::shared_ptr SLVertexColumn::dup() const { - SLVertexColumnBuilder builder(label_); - for (auto v : vertices_) { - builder.push_back_opt(v); - } - return builder.finish(); -} - -std::shared_ptr SLVertexColumnBuilder::finish() { - auto ret = std::make_shared(label_); - ret->vertices_.swap(vertices_); - return ret; -} - -std::shared_ptr MSVertexColumn::shuffle( - const std::vector& offsets) const { - MLVertexColumnBuilder builder; - builder.reserve(offsets.size()); - for (auto offset : offsets) { - builder.push_back_vertex(get_vertex(offset)); - } - return builder.finish(); -} - -std::shared_ptr MSVertexColumn::dup() const { - MSVertexColumnBuilder builder; - for (auto& pair : vertices_) { - for (auto v : pair.second) { - builder.push_back_vertex(std::make_pair(pair.first, v)); - } - } - return builder.finish(); -} - -ISigColumn* SLVertexColumn::generate_signature() const { - return new SigColumn(vertices_); -} - -ISigColumn* MSVertexColumn::generate_signature() const { - LOG(FATAL) << "not implemented..."; - return nullptr; -} - -std::shared_ptr MSVertexColumnBuilder::finish() { - if (!cur_list_.empty()) { - vertices_.emplace_back(cur_label_, std::move(cur_list_)); - cur_list_.clear(); - } - auto ret = std::make_shared(); - auto& label_set = ret->labels_; - for (auto& pair : vertices_) { - label_set.insert(pair.first); - } - ret->vertices_.swap(vertices_); - return ret; -} - -std::shared_ptr MLVertexColumn::shuffle( - const std::vector& offsets) const { - MLVertexColumnBuilder builder(labels_); - builder.reserve(offsets.size()); - for (auto offset : offsets) { - builder.push_back_vertex(vertices_[offset]); - } - return builder.finish(); -} - -ISigColumn* MLVertexColumn::generate_signature() const { - return new SigColumn>(vertices_); -} - -void MLVertexColumn::generate_dedup_offset(std::vector& offsets) const { - offsets.clear(); - std::set> vset; - size_t n = vertices_.size(); - for (size_t i = 0; i != n; ++i) { - auto cur = vertices_[i]; - if (vset.find(cur) == vset.end()) { - offsets.push_back(i); - vset.insert(cur); - } - } -} - -std::shared_ptr MLVertexColumn::dup() const { - MLVertexColumnBuilder builder(labels_); - for (auto& pair : vertices_) { - builder.push_back_vertex(pair); - } - return builder.finish(); -} - -std::shared_ptr MLVertexColumnBuilder::finish() { - auto ret = std::make_shared(); - ret->vertices_.swap(vertices_); - ret->labels_.swap(labels_); - return ret; -} - -void OptionalSLVertexColumn::generate_dedup_offset( - std::vector& offsets) const { - offsets.clear(); - std::vector bitset; - size_t vnum = vertices_.size(); - bitset.resize(vnum); - bool flag = false; - size_t idx = 0; - for (size_t i = 0; i < vnum; ++i) { - vid_t v = vertices_[i]; - if (v == std::numeric_limits::max()) { - if (!flag) { - flag = true; - idx = i; - continue; - } - } - if (bitset.size() <= v) { - bitset.resize(v + 1); - bitset[v] = true; - offsets.push_back(i); - } else { - if (!bitset[v]) { - offsets.push_back(i); - bitset[v] = true; - } - } - } - if (flag) { - offsets.push_back(idx); - } -} - -std::shared_ptr OptionalSLVertexColumn::dup() const { - OptionalSLVertexColumnBuilder builder(label_); - for (auto v : vertices_) { - builder.push_back_opt(v); - } - return builder.finish(); -} - -std::shared_ptr OptionalSLVertexColumn::shuffle( - const std::vector& offsets) const { - OptionalSLVertexColumnBuilder builder(label_); - builder.reserve(offsets.size()); - for (auto offset : offsets) { - builder.push_back_opt(vertices_[offset]); - } - return builder.finish(); -} - -ISigColumn* OptionalSLVertexColumn::generate_signature() const { - return new SigColumn(vertices_); -} - -std::shared_ptr OptionalSLVertexColumnBuilder::finish() { - auto ret = std::make_shared(label_); - ret->vertices_.swap(vertices_); - return ret; -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/columns/vertex_columns.h b/flex/engines/graph_db/runtime/common/columns/vertex_columns.h index 108ac48d5e5e..16bd79ff9af7 100644 --- a/flex/engines/graph_db/runtime/common/columns/vertex_columns.h +++ b/flex/engines/graph_db/runtime/common/columns/vertex_columns.h @@ -472,6 +472,232 @@ void foreach_vertex(const IVertexColumn& col, const FUNC_T& func) { } } +std::shared_ptr SLVertexColumn::shuffle( + const std::vector& offsets) const { + SLVertexColumnBuilder builder(label_); + builder.reserve(offsets.size()); + for (auto offset : offsets) { + builder.push_back_opt(vertices_[offset]); + } + return builder.finish(); +} + +void SLVertexColumn::generate_dedup_offset(std::vector& offsets) const { + offsets.clear(); +#if 0 + std::set vset; + size_t n = vertices_.size(); + for (size_t i = 0; i != n; ++i) { + vid_t cur = vertices_[i]; + if (vset.find(cur) == vset.end()) { + offsets.push_back(i); + vset.insert(cur); + } + } +#else + std::vector bitset; + size_t vnum = vertices_.size(); + bitset.resize(vnum); + for (size_t i = 0; i < vnum; ++i) { + vid_t v = vertices_[i]; + if (bitset.size() <= v) { + bitset.resize(v + 1); + bitset[v] = true; + + offsets.push_back(i); + } else { + if (!bitset[v]) { + offsets.push_back(i); + bitset[v] = true; + } + } + } +#endif +} + +std::shared_ptr SLVertexColumn::union_col( + std::shared_ptr other) const { + CHECK(other->column_type() == ContextColumnType::kVertex); + const IVertexColumn& vertex_column = + *std::dynamic_pointer_cast(other); + if (vertex_column.vertex_column_type() == VertexColumnType::kSingle) { + const SLVertexColumn& col = + dynamic_cast(vertex_column); + if (label() == col.label()) { + SLVertexColumnBuilder builder(label()); + for (auto v : vertices_) { + builder.push_back_opt(v); + } + for (auto v : col.vertices_) { + builder.push_back_opt(v); + } + return builder.finish(); + } + } + LOG(FATAL) << "not support..."; + return nullptr; +} + +std::shared_ptr SLVertexColumn::dup() const { + SLVertexColumnBuilder builder(label_); + for (auto v : vertices_) { + builder.push_back_opt(v); + } + return builder.finish(); +} + +std::shared_ptr SLVertexColumnBuilder::finish() { + auto ret = std::make_shared(label_); + ret->vertices_.swap(vertices_); + return ret; +} + +std::shared_ptr MSVertexColumn::shuffle( + const std::vector& offsets) const { + MLVertexColumnBuilder builder; + builder.reserve(offsets.size()); + for (auto offset : offsets) { + builder.push_back_vertex(get_vertex(offset)); + } + return builder.finish(); +} + +std::shared_ptr MSVertexColumn::dup() const { + MSVertexColumnBuilder builder; + for (auto& pair : vertices_) { + for (auto v : pair.second) { + builder.push_back_vertex(std::make_pair(pair.first, v)); + } + } + return builder.finish(); +} + +ISigColumn* SLVertexColumn::generate_signature() const { + return new SigColumn(vertices_); +} + +ISigColumn* MSVertexColumn::generate_signature() const { + LOG(FATAL) << "not implemented..."; + return nullptr; +} + +std::shared_ptr MSVertexColumnBuilder::finish() { + if (!cur_list_.empty()) { + vertices_.emplace_back(cur_label_, std::move(cur_list_)); + cur_list_.clear(); + } + auto ret = std::make_shared(); + auto& label_set = ret->labels_; + for (auto& pair : vertices_) { + label_set.insert(pair.first); + } + ret->vertices_.swap(vertices_); + return ret; +} + +std::shared_ptr MLVertexColumn::shuffle( + const std::vector& offsets) const { + MLVertexColumnBuilder builder(labels_); + builder.reserve(offsets.size()); + for (auto offset : offsets) { + builder.push_back_vertex(vertices_[offset]); + } + return builder.finish(); +} + +ISigColumn* MLVertexColumn::generate_signature() const { + return new SigColumn>(vertices_); +} + +void MLVertexColumn::generate_dedup_offset(std::vector& offsets) const { + offsets.clear(); + std::set> vset; + size_t n = vertices_.size(); + for (size_t i = 0; i != n; ++i) { + auto cur = vertices_[i]; + if (vset.find(cur) == vset.end()) { + offsets.push_back(i); + vset.insert(cur); + } + } +} + +std::shared_ptr MLVertexColumn::dup() const { + MLVertexColumnBuilder builder(labels_); + for (auto& pair : vertices_) { + builder.push_back_vertex(pair); + } + return builder.finish(); +} + +std::shared_ptr MLVertexColumnBuilder::finish() { + auto ret = std::make_shared(); + ret->vertices_.swap(vertices_); + ret->labels_.swap(labels_); + return ret; +} + +void OptionalSLVertexColumn::generate_dedup_offset( + std::vector& offsets) const { + offsets.clear(); + std::vector bitset; + size_t vnum = vertices_.size(); + bitset.resize(vnum); + bool flag = false; + size_t idx = 0; + for (size_t i = 0; i < vnum; ++i) { + vid_t v = vertices_[i]; + if (v == std::numeric_limits::max()) { + if (!flag) { + flag = true; + idx = i; + continue; + } + } + if (bitset.size() <= v) { + bitset.resize(v + 1); + bitset[v] = true; + offsets.push_back(i); + } else { + if (!bitset[v]) { + offsets.push_back(i); + bitset[v] = true; + } + } + } + if (flag) { + offsets.push_back(idx); + } +} + +std::shared_ptr OptionalSLVertexColumn::dup() const { + OptionalSLVertexColumnBuilder builder(label_); + for (auto v : vertices_) { + builder.push_back_opt(v); + } + return builder.finish(); +} + +std::shared_ptr OptionalSLVertexColumn::shuffle( + const std::vector& offsets) const { + OptionalSLVertexColumnBuilder builder(label_); + builder.reserve(offsets.size()); + for (auto offset : offsets) { + builder.push_back_opt(vertices_[offset]); + } + return builder.finish(); +} + +ISigColumn* OptionalSLVertexColumn::generate_signature() const { + return new SigColumn(vertices_); +} + +std::shared_ptr OptionalSLVertexColumnBuilder::finish() { + auto ret = std::make_shared(label_); + ret->vertices_.swap(vertices_); + return ret; +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/context.cc b/flex/engines/graph_db/runtime/common/context.cc deleted file mode 100644 index 11d6edf5c54b..000000000000 --- a/flex/engines/graph_db/runtime/common/context.cc +++ /dev/null @@ -1,244 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/context.h" -#include "flex/engines/graph_db/runtime/common/columns/value_columns.h" -#include "flex/engines/graph_db/runtime/common/columns/vertex_columns.h" - -namespace gs { - -namespace runtime { - -Context::Context() : head(nullptr) {} - -void Context::clear() { - columns.clear(); - head.reset(); - idx_columns.clear(); - tag_ids.clear(); -} - -Context Context::dup() const { - Context new_ctx; - new_ctx.head = nullptr; - for (auto col : columns) { - if (col != nullptr) { - new_ctx.columns.push_back(col->dup()); - if (col == head) { - new_ctx.head = new_ctx.columns.back(); - } - } else { - new_ctx.columns.push_back(nullptr); - } - } - if (head != nullptr && new_ctx.head == nullptr) { - new_ctx.head = head->dup(); - } - for (auto& idx_col : idx_columns) { - new_ctx.idx_columns.emplace_back( - std::dynamic_pointer_cast>(idx_col->dup())); - } - new_ctx.tag_ids = tag_ids; - return new_ctx; -} - -void Context::update_tag_ids(const std::vector& tag_ids) { - this->tag_ids = tag_ids; -} - -void Context::append_tag_id(size_t tag_id) { - if (std::find(tag_ids.begin(), tag_ids.end(), tag_id) == tag_ids.end()) { - tag_ids.push_back(tag_id); - } -} - -void Context::set(int alias, std::shared_ptr col) { - head = col; - if (alias >= 0) { - if (columns.size() <= static_cast(alias)) { - columns.resize(alias + 1, nullptr); - } - assert(columns[alias] == nullptr); - columns[alias] = col; - } -} - -void Context::set_with_reshuffle(int alias, std::shared_ptr col, - const std::vector& offsets) { - head.reset(); - head = nullptr; - - if (alias >= 0) { - if (columns.size() > static_cast(alias) && - columns[alias] != nullptr) { - columns[alias].reset(); - columns[alias] = nullptr; - } - } - - reshuffle(offsets); - set(alias, col); -} - -void Context::set_with_reshuffle_beta(int alias, - std::shared_ptr col, - const std::vector& offsets, - const std::set& keep_cols) { - head.reset(); - head = nullptr; - if (alias >= 0) { - if (columns.size() > static_cast(alias) && - columns[alias] != nullptr) { - columns[alias].reset(); - columns[alias] = nullptr; - } - } - for (size_t k = 0; k < columns.size(); ++k) { - if (keep_cols.find(k) == keep_cols.end() && columns[k] != nullptr) { - columns[k].reset(); - columns[k] = nullptr; - } - } - - reshuffle(offsets); - - set(alias, col); -} - -void Context::reshuffle(const std::vector& offsets) { - bool head_shuffled = false; - std::vector> new_cols; - - for (auto col : columns) { - if (col == nullptr) { - new_cols.push_back(nullptr); - - continue; - } - if (col == head) { - head = col->shuffle(offsets); - new_cols.push_back(head); - head_shuffled = true; - } else { - new_cols.push_back(col->shuffle(offsets)); - } - } - if (!head_shuffled && head != nullptr) { - head = head->shuffle(offsets); - } - std::swap(new_cols, columns); - std::vector>> new_idx_columns; - for (auto& idx_col : idx_columns) { - new_idx_columns.emplace_back(std::dynamic_pointer_cast>( - idx_col->shuffle(offsets))); - } - std::swap(new_idx_columns, idx_columns); -} - -std::shared_ptr Context::get(int alias) { - if (alias == -1) { - return head; - } - assert(static_cast(alias) < columns.size()); - return columns[alias]; -} - -const std::shared_ptr Context::get(int alias) const { - if (alias == -1) { - assert(head != nullptr); - return head; - } - assert(static_cast(alias) < columns.size()); - // return nullptr if the column is not set - return columns[alias]; -} - -size_t Context::row_num() const { - for (auto col : columns) { - if (col != nullptr) { - return col->size(); - } - } - if (head != nullptr) { - return head->size(); - } - return 0; -} - -void Context::desc(const std::string& info) const { - if (!info.empty()) { - LOG(INFO) << info; - } - for (size_t col_i = 0; col_i < col_num(); ++col_i) { - if (columns[col_i] != nullptr) { - LOG(INFO) << "\tcol-" << col_i << ": " << columns[col_i]->column_info(); - } - } - LOG(INFO) << "\thead: " << ((head == nullptr) ? "NULL" : head->column_info()); -} - -void Context::show(const ReadTransaction& txn) const { - size_t rn = row_num(); - size_t cn = col_num(); - for (size_t ri = 0; ri < rn; ++ri) { - std::string line; - for (size_t ci = 0; ci < cn; ++ci) { - if (columns[ci] != nullptr && - columns[ci]->column_type() == ContextColumnType::kVertex) { - auto v = std::dynamic_pointer_cast(columns[ci]) - ->get_vertex(ri); - int64_t id = txn.GetVertexId(v.first, v.second).AsInt64(); - line += std::to_string(id); - line += ", "; - } else if (columns[ci] != nullptr) { - line += columns[ci]->get_elem(ri).to_string(); - line += ", "; - } - } - LOG(INFO) << line; - } -} - -void Context::generate_idx_col(int idx) { - size_t n = row_num(); - ValueColumnBuilder builder; - builder.reserve(n); - for (size_t k = 0; k < n; ++k) { - builder.push_back_opt(k); - } - set(idx, builder.finish()); -} - -size_t Context::col_num() const { return columns.size(); } - -void Context::push_idx_col() { - ValueColumnBuilder builder; - builder.reserve(row_num()); - for (size_t k = 0; k < row_num(); ++k) { - builder.push_back_opt(k); - } - idx_columns.emplace_back( - std::dynamic_pointer_cast>(builder.finish())); -} - -const ValueColumn& Context::get_idx_col() const { - return *idx_columns.back(); -} - -void Context::pop_idx_col() { idx_columns.pop_back(); } - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/context.h b/flex/engines/graph_db/runtime/common/context.h index ed32d93006a6..2fc1d2379380 100644 --- a/flex/engines/graph_db/runtime/common/context.h +++ b/flex/engines/graph_db/runtime/common/context.h @@ -55,7 +55,8 @@ class Context { void desc(const std::string& info = "") const; - void show(const ReadTransaction& txn) const; + template + void show(const GraphInterface& txn) const; void generate_idx_col(int idx); @@ -73,6 +74,224 @@ class Context { std::vector tag_ids; }; +Context::Context() : head(nullptr) {} + +void Context::clear() { + columns.clear(); + head.reset(); + idx_columns.clear(); + tag_ids.clear(); +} + +Context Context::dup() const { + Context new_ctx; + new_ctx.head = nullptr; + for (auto col : columns) { + if (col != nullptr) { + new_ctx.columns.push_back(col->dup()); + if (col == head) { + new_ctx.head = new_ctx.columns.back(); + } + } else { + new_ctx.columns.push_back(nullptr); + } + } + if (head != nullptr && new_ctx.head == nullptr) { + new_ctx.head = head->dup(); + } + for (auto& idx_col : idx_columns) { + new_ctx.idx_columns.emplace_back( + std::dynamic_pointer_cast>(idx_col->dup())); + } + new_ctx.tag_ids = tag_ids; + return new_ctx; +} + +void Context::update_tag_ids(const std::vector& tag_ids) { + this->tag_ids = tag_ids; +} + +void Context::append_tag_id(size_t tag_id) { + if (std::find(tag_ids.begin(), tag_ids.end(), tag_id) == tag_ids.end()) { + tag_ids.push_back(tag_id); + } +} + +void Context::set(int alias, std::shared_ptr col) { + head = col; + if (alias >= 0) { + if (columns.size() <= static_cast(alias)) { + columns.resize(alias + 1, nullptr); + } + assert(columns[alias] == nullptr); + columns[alias] = col; + } +} + +void Context::set_with_reshuffle(int alias, std::shared_ptr col, + const std::vector& offsets) { + head.reset(); + head = nullptr; + + if (alias >= 0) { + if (columns.size() > static_cast(alias) && + columns[alias] != nullptr) { + columns[alias].reset(); + columns[alias] = nullptr; + } + } + + reshuffle(offsets); + set(alias, col); +} + +void Context::set_with_reshuffle_beta(int alias, + std::shared_ptr col, + const std::vector& offsets, + const std::set& keep_cols) { + head.reset(); + head = nullptr; + if (alias >= 0) { + if (columns.size() > static_cast(alias) && + columns[alias] != nullptr) { + columns[alias].reset(); + columns[alias] = nullptr; + } + } + for (size_t k = 0; k < columns.size(); ++k) { + if (keep_cols.find(k) == keep_cols.end() && columns[k] != nullptr) { + columns[k].reset(); + columns[k] = nullptr; + } + } + + reshuffle(offsets); + + set(alias, col); +} + +void Context::reshuffle(const std::vector& offsets) { + bool head_shuffled = false; + std::vector> new_cols; + + for (auto col : columns) { + if (col == nullptr) { + new_cols.push_back(nullptr); + + continue; + } + if (col == head) { + head = col->shuffle(offsets); + new_cols.push_back(head); + head_shuffled = true; + } else { + new_cols.push_back(col->shuffle(offsets)); + } + } + if (!head_shuffled && head != nullptr) { + head = head->shuffle(offsets); + } + std::swap(new_cols, columns); + std::vector>> new_idx_columns; + for (auto& idx_col : idx_columns) { + new_idx_columns.emplace_back(std::dynamic_pointer_cast>( + idx_col->shuffle(offsets))); + } + std::swap(new_idx_columns, idx_columns); +} + +std::shared_ptr Context::get(int alias) { + if (alias == -1) { + return head; + } + assert(static_cast(alias) < columns.size()); + return columns[alias]; +} + +const std::shared_ptr Context::get(int alias) const { + if (alias == -1) { + assert(head != nullptr); + return head; + } + assert(static_cast(alias) < columns.size()); + // return nullptr if the column is not set + return columns[alias]; +} + +size_t Context::row_num() const { + for (auto col : columns) { + if (col != nullptr) { + return col->size(); + } + } + if (head != nullptr) { + return head->size(); + } + return 0; +} + +void Context::desc(const std::string& info) const { + if (!info.empty()) { + LOG(INFO) << info; + } + for (size_t col_i = 0; col_i < col_num(); ++col_i) { + if (columns[col_i] != nullptr) { + LOG(INFO) << "\tcol-" << col_i << ": " << columns[col_i]->column_info(); + } + } + LOG(INFO) << "\thead: " << ((head == nullptr) ? "NULL" : head->column_info()); +} + +template +void Context::show(const GraphInterface& txn) const { + size_t rn = row_num(); + size_t cn = col_num(); + for (size_t ri = 0; ri < rn; ++ri) { + std::string line; + for (size_t ci = 0; ci < cn; ++ci) { + if (columns[ci] != nullptr && + columns[ci]->column_type() == ContextColumnType::kVertex) { + auto v = std::dynamic_pointer_cast(columns[ci]) + ->get_vertex(ri); + int64_t id = txn.GetVertexId(v.first, v.second).AsInt64(); + line += std::to_string(id); + line += ", "; + } else if (columns[ci] != nullptr) { + line += columns[ci]->get_elem(ri).to_string(); + line += ", "; + } + } + LOG(INFO) << line; + } +} + +void Context::generate_idx_col(int idx) { + size_t n = row_num(); + ValueColumnBuilder builder; + builder.reserve(n); + for (size_t k = 0; k < n; ++k) { + builder.push_back_opt(k); + } + set(idx, builder.finish()); +} + +size_t Context::col_num() const { return columns.size(); } + +void Context::push_idx_col() { + ValueColumnBuilder builder; + builder.reserve(row_num()); + for (size_t k = 0; k < row_num(); ++k) { + builder.push_back_opt(k); + } + idx_columns.emplace_back( + std::dynamic_pointer_cast>(builder.finish())); +} + +const ValueColumn& Context::get_idx_col() const { + return *idx_columns.back(); +} + +void Context::pop_idx_col() { idx_columns.pop_back(); } } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/dedup.cc b/flex/engines/graph_db/runtime/common/operators/dedup.cc deleted file mode 100644 index 7caf2119c58d..000000000000 --- a/flex/engines/graph_db/runtime/common/operators/dedup.cc +++ /dev/null @@ -1,128 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/operators/dedup.h" - -namespace gs { - -namespace runtime { - -void Dedup::dedup(const ReadTransaction& txn, Context& ctx, - const std::vector& cols) { - size_t row_num = ctx.row_num(); - std::vector offsets; - if (cols.size() == 0) { - return; - } else if (cols.size() == 1) { - ctx.get(cols[0])->generate_dedup_offset(offsets); - } else if (cols.size() == 2) { - ISigColumn* sig0 = ctx.get(cols[0])->generate_signature(); - ISigColumn* sig1 = ctx.get(cols[1])->generate_signature(); -#if 0 - std::set> sigset; - for (size_t r_i = 0; r_i < row_num; ++r_i) { - auto cur = std::make_pair(sig0->get_sig(r_i), sig1->get_sig(r_i)); - if (sigset.find(cur) == sigset.end()) { - offsets.push_back(r_i); - sigset.insert(cur); - } - } -#else - std::vector> list; - for (size_t r_i = 0; r_i < row_num; ++r_i) { - list.emplace_back(sig0->get_sig(r_i), sig1->get_sig(r_i), r_i); - } - std::sort(list.begin(), list.end()); - size_t list_size = list.size(); - if (list_size > 0) { - offsets.push_back(std::get<2>(list[0])); - for (size_t k = 1; k < list_size; ++k) { - if (std::get<0>(list[k]) != std::get<0>(list[k - 1]) || - std::get<1>(list[k]) != std::get<1>(list[k - 1])) { - offsets.push_back(std::get<2>(list[k])); - } - } - std::sort(offsets.begin(), offsets.end()); - } -#endif - delete sig0; - delete sig1; - } else if (cols.size() == 3) { - std::set> sigset; - ISigColumn* sig0 = ctx.get(cols[0])->generate_signature(); - ISigColumn* sig1 = ctx.get(cols[1])->generate_signature(); - ISigColumn* sig2 = ctx.get(cols[2])->generate_signature(); - for (size_t r_i = 0; r_i < row_num; ++r_i) { - auto cur = std::make_tuple(sig0->get_sig(r_i), sig1->get_sig(r_i), - sig2->get_sig(r_i)); - if (sigset.find(cur) == sigset.end()) { - offsets.push_back(r_i); - sigset.insert(cur); - } - } - delete sig0; - delete sig1; - delete sig2; - } else { - std::set set; - for (size_t r_i = 0; r_i < row_num; ++r_i) { - std::vector bytes; - Encoder encoder(bytes); - for (size_t c_i = 0; c_i < cols.size(); ++c_i) { - auto val = ctx.get(cols[c_i])->get_elem(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - std::string cur(bytes.begin(), bytes.end()); - if (set.find(cur) == set.end()) { - offsets.push_back(r_i); - set.insert(cur); - } - } - } - ctx.reshuffle(offsets); -} - -void Dedup::dedup(const ReadTransaction& txn, Context& ctx, - const std::vector& cols, - const std::vector>& vars) { - std::set set; - size_t row_num = ctx.row_num(); - std::vector offsets; - for (size_t r_i = 0; r_i < row_num; ++r_i) { - std::vector bytes; - Encoder encoder(bytes); - for (size_t c_i = 0; c_i < cols.size(); ++c_i) { - auto val = ctx.get(cols[c_i])->get_elem(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - for (auto& var : vars) { - auto val = var(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - std::string cur(bytes.begin(), bytes.end()); - if (set.find(cur) == set.end()) { - offsets.push_back(r_i); - set.insert(cur); - } - } - ctx.reshuffle(offsets); -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/dedup.h b/flex/engines/graph_db/runtime/common/operators/dedup.h index fbf192232bb5..2ded29c7e860 100644 --- a/flex/engines/graph_db/runtime/common/operators/dedup.h +++ b/flex/engines/graph_db/runtime/common/operators/dedup.h @@ -28,13 +28,122 @@ namespace runtime { class Dedup { public: - static void dedup(const ReadTransaction& txn, Context& ctx, + template + static void dedup(const GraphInterface& txn, Context& ctx, const std::vector& cols); - static void dedup(const ReadTransaction& txn, Context& ctx, + + template + static void dedup(const GraphInterface& txn, Context& ctx, const std::vector& cols, const std::vector>& vars); }; +template +void Dedup::dedup(const GraphInterface& txn, Context& ctx, + const std::vector& cols) { + size_t row_num = ctx.row_num(); + std::vector offsets; + if (cols.size() == 0) { + return; + } else if (cols.size() == 1) { + ctx.get(cols[0])->generate_dedup_offset(offsets); + } else if (cols.size() == 2) { + ISigColumn* sig0 = ctx.get(cols[0])->generate_signature(); + ISigColumn* sig1 = ctx.get(cols[1])->generate_signature(); +#if 0 + std::set> sigset; + for (size_t r_i = 0; r_i < row_num; ++r_i) { + auto cur = std::make_pair(sig0->get_sig(r_i), sig1->get_sig(r_i)); + if (sigset.find(cur) == sigset.end()) { + offsets.push_back(r_i); + sigset.insert(cur); + } + } +#else + std::vector> list; + for (size_t r_i = 0; r_i < row_num; ++r_i) { + list.emplace_back(sig0->get_sig(r_i), sig1->get_sig(r_i), r_i); + } + std::sort(list.begin(), list.end()); + size_t list_size = list.size(); + if (list_size > 0) { + offsets.push_back(std::get<2>(list[0])); + for (size_t k = 1; k < list_size; ++k) { + if (std::get<0>(list[k]) != std::get<0>(list[k - 1]) || + std::get<1>(list[k]) != std::get<1>(list[k - 1])) { + offsets.push_back(std::get<2>(list[k])); + } + } + std::sort(offsets.begin(), offsets.end()); + } +#endif + delete sig0; + delete sig1; + } else if (cols.size() == 3) { + std::set> sigset; + ISigColumn* sig0 = ctx.get(cols[0])->generate_signature(); + ISigColumn* sig1 = ctx.get(cols[1])->generate_signature(); + ISigColumn* sig2 = ctx.get(cols[2])->generate_signature(); + for (size_t r_i = 0; r_i < row_num; ++r_i) { + auto cur = std::make_tuple(sig0->get_sig(r_i), sig1->get_sig(r_i), + sig2->get_sig(r_i)); + if (sigset.find(cur) == sigset.end()) { + offsets.push_back(r_i); + sigset.insert(cur); + } + } + delete sig0; + delete sig1; + delete sig2; + } else { + std::set set; + for (size_t r_i = 0; r_i < row_num; ++r_i) { + std::vector bytes; + Encoder encoder(bytes); + for (size_t c_i = 0; c_i < cols.size(); ++c_i) { + auto val = ctx.get(cols[c_i])->get_elem(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + std::string cur(bytes.begin(), bytes.end()); + if (set.find(cur) == set.end()) { + offsets.push_back(r_i); + set.insert(cur); + } + } + } + ctx.reshuffle(offsets); +} + +template +void Dedup::dedup(const GraphInterface& txn, Context& ctx, + const std::vector& cols, + const std::vector>& vars) { + std::set set; + size_t row_num = ctx.row_num(); + std::vector offsets; + for (size_t r_i = 0; r_i < row_num; ++r_i) { + std::vector bytes; + Encoder encoder(bytes); + for (size_t c_i = 0; c_i < cols.size(); ++c_i) { + auto val = ctx.get(cols[c_i])->get_elem(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + for (auto& var : vars) { + auto val = var(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + std::string cur(bytes.begin(), bytes.end()); + if (set.find(cur) == set.end()) { + offsets.push_back(r_i); + set.insert(cur); + } + } + ctx.reshuffle(offsets); +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/edge_expand.cc b/flex/engines/graph_db/runtime/common/operators/edge_expand.cc deleted file mode 100644 index d94f9017afa1..000000000000 --- a/flex/engines/graph_db/runtime/common/operators/edge_expand.cc +++ /dev/null @@ -1,855 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/operators/edge_expand.h" - -namespace gs { - -namespace runtime { - -static std::vector get_expand_label_set( - const ReadTransaction& txn, const std::set& label_set, - const std::vector& labels, Direction dir) { - std::vector label_triplets; - if (dir == Direction::kOut) { - for (auto& triplet : labels) { - if (label_set.count(triplet.src_label)) { - label_triplets.emplace_back(triplet); - } - } - } else if (dir == Direction::kIn) { - for (auto& triplet : labels) { - if (label_set.count(triplet.dst_label)) { - label_triplets.emplace_back(triplet); - } - } - } else { - for (auto& triplet : labels) { - if (label_set.count(triplet.src_label) || - label_set.count(triplet.dst_label)) { - label_triplets.emplace_back(triplet); - } - } - } - return label_triplets; -} - -bl::result EdgeExpand::expand_edge_without_predicate( - const ReadTransaction& txn, Context&& ctx, const EdgeExpandParams& params) { - std::vector shuffle_offset; - - if (params.labels.size() == 1) { - if (params.dir == Direction::kIn) { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.v_tag)); - label_t output_vertex_label = params.labels[0].src_label; - label_t edge_label = params.labels[0].edge_label; - - auto& props = txn.schema().get_edge_properties( - params.labels[0].src_label, params.labels[0].dst_label, - params.labels[0].edge_label); - PropertyType pt = PropertyType::kEmpty; - if (props.size() > 1) { - pt = PropertyType::kRecordView; - - } else if (!props.empty()) { - pt = props[0]; - } - - SDSLEdgeColumnBuilder builder(Direction::kIn, params.labels[0], pt, - props); - - label_t dst_label = params.labels[0].dst_label; - foreach_vertex(input_vertex_list, - [&](size_t index, label_t label, vid_t v) { - if (label != dst_label) { - return; - } - auto ie_iter = txn.GetInEdgeIterator( - label, v, output_vertex_label, edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - CHECK(ie_iter.GetData().type == pt) - << ie_iter.GetData().type << " " << pt; - builder.push_back_opt(nbr, v, ie_iter.GetData()); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - }); - - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - return ctx; - } else if (params.dir == Direction::kOut) { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.v_tag)); - label_t output_vertex_label = params.labels[0].dst_label; - label_t edge_label = params.labels[0].edge_label; - - auto& props = txn.schema().get_edge_properties( - params.labels[0].src_label, params.labels[0].dst_label, - params.labels[0].edge_label); - PropertyType pt = PropertyType::kEmpty; - - if (!props.empty()) { - pt = props[0]; - } - if (props.size() > 1) { - pt = PropertyType::kRecordView; - } - - SDSLEdgeColumnBuilder builder(Direction::kOut, params.labels[0], pt, - props); - label_t src_label = params.labels[0].src_label; - foreach_vertex(input_vertex_list, - [&](size_t index, label_t label, vid_t v) { - if (label != src_label) { - return; - } - auto oe_iter = txn.GetOutEdgeIterator( - label, v, output_vertex_label, edge_label); - - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - CHECK(oe_iter.GetData().type == pt); - builder.push_back_opt(v, nbr, oe_iter.GetData()); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - }); - - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - return ctx; - } else { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.v_tag)); - auto props = txn.schema().get_edge_properties( - params.labels[0].src_label, params.labels[0].dst_label, - params.labels[0].edge_label); - PropertyType pt = PropertyType::kEmpty; - if (!props.empty()) { - pt = props[0]; - } - BDSLEdgeColumnBuilder builder(params.labels[0], pt); - foreach_vertex(input_vertex_list, [&](size_t index, label_t label, - vid_t v) { - if (label == params.labels[0].src_label) { - auto oe_iter = - txn.GetOutEdgeIterator(label, v, params.labels[0].dst_label, - params.labels[0].edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(v, nbr, oe_iter.GetData(), Direction::kOut); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - if (label == params.labels[0].dst_label) { - auto ie_iter = - txn.GetInEdgeIterator(label, v, params.labels[0].src_label, - params.labels[0].edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(nbr, v, ie_iter.GetData(), Direction::kIn); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - return ctx; - } - } else { - auto column = - std::dynamic_pointer_cast(ctx.get(params.v_tag)); - auto label_set = column->get_labels_set(); - auto labels = - get_expand_label_set(txn, label_set, params.labels, params.dir); - std::vector> label_props; - std::vector> props_vec; - for (auto& triplet : labels) { - auto& props = txn.schema().get_edge_properties( - triplet.src_label, triplet.dst_label, triplet.edge_label); - PropertyType pt = PropertyType::kEmpty; - if (!props.empty()) { - pt = props[0]; - } - if (props.size() > 1) { - pt = PropertyType::kRecordView; - } - props_vec.emplace_back(props); - label_props.emplace_back(triplet, pt); - } - if (params.dir == Direction::kOut || params.dir == Direction::kIn) { - if (labels.size() == 1) { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.v_tag)); - if (params.dir == Direction::kOut) { - auto& triplet = labels[0]; - SDSLEdgeColumnBuilder builder(Direction::kOut, triplet, - label_props[0].second, props_vec[0]); - foreach_vertex( - input_vertex_list, [&](size_t index, label_t label, vid_t v) { - if (label == triplet.src_label) { - auto oe_iter = txn.GetOutEdgeIterator( - label, v, triplet.dst_label, triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(v, nbr, oe_iter.GetData()); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), - shuffle_offset); - return ctx; - } else if (params.dir == Direction::kIn) { - auto& triplet = labels[0]; - SDSLEdgeColumnBuilder builder(Direction::kIn, triplet, - label_props[0].second, props_vec[0]); - foreach_vertex( - input_vertex_list, [&](size_t index, label_t label, vid_t v) { - if (label == triplet.dst_label) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, triplet.src_label, triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(nbr, v, ie_iter.GetData()); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), - shuffle_offset); - return ctx; - } - } else if (labels.size() > 1 || labels.size() == 0) { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.v_tag)); - - SDMLEdgeColumnBuilder builder(params.dir, label_props); - if (params.dir == Direction::kOut) { - foreach_vertex(input_vertex_list, [&](size_t index, label_t label, - vid_t v) { - for (auto& triplet : labels) { - if (triplet.src_label == label) { - if (params.dir == Direction::kOut) { - auto oe_iter = txn.GetOutEdgeIterator( - label, v, triplet.dst_label, triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(triplet, v, nbr, oe_iter.GetData()); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - } - } - }); - } else { - foreach_vertex(input_vertex_list, [&](size_t index, label_t label, - vid_t v) { - for (auto& triplet : labels) { - if (triplet.dst_label == label) { - if (params.dir == Direction::kIn) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, triplet.src_label, triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(triplet, nbr, v, ie_iter.GetData()); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - } - } - }); - } - - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - return ctx; - } - } else if (params.dir == Direction::kBoth) { - if (labels.size() == 1) { - BDSLEdgeColumnBuilder builder(labels[0], label_props[0].second); - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.v_tag)); - foreach_vertex(input_vertex_list, [&](size_t index, label_t label, - vid_t v) { - if (label == labels[0].src_label) { - auto oe_iter = txn.GetOutEdgeIterator(label, v, labels[0].dst_label, - labels[0].edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(v, nbr, oe_iter.GetData(), Direction::kOut); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - if (label == labels[0].dst_label) { - auto ie_iter = txn.GetInEdgeIterator(label, v, labels[0].src_label, - labels[0].edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(nbr, v, ie_iter.GetData(), Direction::kIn); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - return ctx; - - } else { - BDMLEdgeColumnBuilder builder(label_props); - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.v_tag)); - foreach_vertex( - input_vertex_list, [&](size_t index, label_t label, vid_t v) { - for (auto& triplet : labels) { - if (triplet.src_label == label) { - auto oe_iter = txn.GetOutEdgeIterator( - label, v, triplet.dst_label, triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(triplet, v, nbr, oe_iter.GetData(), - Direction::kOut); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - if (triplet.dst_label == label) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, triplet.src_label, triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(triplet, nbr, v, ie_iter.GetData(), - Direction::kIn); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - return ctx; - } - } - } - - LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; - RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + - std::to_string(params.dir)); -} - -bl::result EdgeExpand::expand_vertex_without_predicate( - const ReadTransaction& txn, Context&& ctx, const EdgeExpandParams& params) { - std::shared_ptr input_vertex_list = - std::dynamic_pointer_cast(ctx.get(params.v_tag)); - VertexColumnType input_vertex_list_type = - input_vertex_list->vertex_column_type(); - - std::set output_vertex_set; - const std::set& input_vertex_set = - input_vertex_list->get_labels_set(); - if (params.dir == Direction::kOut) { - for (auto& triplet : params.labels) { - if (input_vertex_set.find(triplet.src_label) != input_vertex_set.end()) { - output_vertex_set.insert(triplet.dst_label); - } - } - } else if (params.dir == Direction::kIn) { - for (auto& triplet : params.labels) { - if (input_vertex_set.find(triplet.dst_label) != input_vertex_set.end()) { - output_vertex_set.insert(triplet.src_label); - } - } - } else { - for (auto& triplet : params.labels) { - if (input_vertex_set.find(triplet.src_label) != input_vertex_set.end()) { - output_vertex_set.insert(triplet.dst_label); - } - if (input_vertex_set.find(triplet.dst_label) != input_vertex_set.end()) { - output_vertex_set.insert(triplet.src_label); - } - } - } - - // if (output_vertex_set.empty()) { - // LOG(FATAL) << "output vertex label set is empty..."; - // } - - std::vector shuffle_offset; - - if (output_vertex_set.size() <= 1) { - label_t output_vertex_label = *output_vertex_set.begin(); - SLVertexColumnBuilder builder(output_vertex_label); - - if (input_vertex_list_type == VertexColumnType::kSingle) { - auto casted_input_vertex_list = - std::dynamic_pointer_cast(input_vertex_list); - label_t input_vertex_label = casted_input_vertex_list->label(); - if (params.labels.size() == 1) { - auto& label_triplet = params.labels[0]; - if (params.dir == Direction::kBoth && - label_triplet.src_label == label_triplet.dst_label && - label_triplet.src_label == output_vertex_label && - output_vertex_label == input_vertex_label) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - auto oe_iter = txn.GetOutEdgeIterator(label, v, label, - label_triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - auto ie_iter = txn.GetInEdgeIterator(label, v, label, - label_triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), - shuffle_offset); - } else if (params.dir == Direction::kIn && - label_triplet.src_label == output_vertex_label && - label_triplet.dst_label == input_vertex_label) { - auto& props = txn.schema().get_edge_properties( - label_triplet.src_label, label_triplet.dst_label, - label_triplet.edge_label); - if (props.empty()) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - auto iter = txn.GetInEdgeIterator( - label, v, output_vertex_label, label_triplet.edge_label); - while (iter.IsValid()) { - builder.push_back_opt(iter.GetNeighbor()); - shuffle_offset.push_back(index); - iter.Next(); - } - }); - } else if (props[0] == PropertyType::kDate) { - // also check csr mutability - const TypedMutableCsrBase* csr = - dynamic_cast*>( - txn.graph().get_ie_csr(label_triplet.dst_label, - label_triplet.src_label, - label_triplet.edge_label)); - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - auto slice = csr->get_edges(v); - for (auto& e : slice) { - builder.push_back_opt(e.neighbor); - shuffle_offset.push_back(index); - } - }); - } else { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, output_vertex_label, label_triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - }); - } - // casted_input_vertex_list->foreach_vertex( - // [&](size_t index, label_t label, vid_t v) { - // auto ie_iter = txn.GetInEdgeIterator( - // label, v, output_vertex_label, - // label_triplet.edge_label); - // while (ie_iter.IsValid()) { - // auto nbr = ie_iter.GetNeighbor(); - // builder.push_back_opt(nbr); - // shuffle_offset.push_back(index); - // ie_iter.Next(); - // } - // }); - ctx.set_with_reshuffle(params.alias, builder.finish(), - shuffle_offset); - } else if (params.dir == Direction::kOut && - label_triplet.src_label == input_vertex_label && - label_triplet.dst_label == output_vertex_label) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - auto oe_iter = txn.GetOutEdgeIterator( - label, v, output_vertex_label, label_triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), - shuffle_offset); - } else { - LOG(ERROR) << "Unsupported edge expand direction"; - RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction"); - } - } else { - MLVertexColumnBuilder builder; - if (params.dir == Direction::kOut || params.dir == Direction::kIn) { - if (params.dir == Direction::kOut) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - for (auto& triplet : params.labels) { - if (triplet.src_label == label) { - auto oe_iter = txn.GetOutEdgeIterator( - label, v, triplet.dst_label, triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_vertex( - std::make_pair(triplet.dst_label, nbr)); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - } - }); - } else { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - for (auto& triplet : params.labels) { - if (triplet.dst_label == label) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, triplet.src_label, triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_vertex( - std::make_pair(triplet.src_label, nbr)); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - } - }); - } - ctx.set_with_reshuffle(params.alias, builder.finish(), - shuffle_offset); - } - } - } else if (input_vertex_list_type == VertexColumnType::kMultiple) { - auto casted_input_vertex_list = - std::dynamic_pointer_cast(input_vertex_list); - if (params.dir == Direction::kBoth) { - LOG(ERROR) << "Unsupported edge expand direction"; - RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction"); - } else if (params.dir == Direction::kIn) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - for (auto& triplet : params.labels) { - if (triplet.dst_label == label) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, triplet.src_label, triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - } else if (params.dir == Direction::kOut) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - for (auto& triplet : params.labels) { - if (triplet.src_label == label) { - auto oe_iter = txn.GetOutEdgeIterator( - label, v, triplet.dst_label, triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - } else { - LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; - RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + - std::to_string(params.dir)); - } - } else if (input_vertex_list_type == VertexColumnType::kMultiSegment) { - auto casted_input_vertex_list = - std::dynamic_pointer_cast(input_vertex_list); - if (params.dir == Direction::kBoth) { - LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; - RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + - std::to_string(params.dir)); - } else if (params.dir == Direction::kIn) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - for (auto& triplet : params.labels) { - if (triplet.dst_label == label) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, triplet.src_label, triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - } else if (params.dir == Direction::kOut) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - for (auto& triplet : params.labels) { - if (triplet.src_label == label) { - auto oe_iter = txn.GetOutEdgeIterator( - label, v, triplet.dst_label, triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - } else { - LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; - RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + - std::to_string(params.dir)); - } - } else { - LOG(ERROR) << "unexpected input vertex list type"; - RETURN_UNSUPPORTED_ERROR("unexpected input vertex list type"); - } - } else { - if (input_vertex_list_type == VertexColumnType::kSingle) { - auto casted_input_vertex_list = - std::dynamic_pointer_cast(input_vertex_list); - label_t input_vertex_label = casted_input_vertex_list->label(); -#if 0 - MLVertexColumnBuilder builder; - for (label_t output_vertex_label : output_vertex_set) { - if (params.dir == Direction::kBoth) { - LOG(FATAL) << "AAAAA"; - } else if (params.dir == Direction::kIn) { - for (auto& triplet : params.labels) { - if (triplet.dst_label == input_vertex_label && - triplet.src_label == output_vertex_label) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, output_vertex_label, triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_vertex( - std::make_pair(output_vertex_label, nbr)); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - }); - } - } - } else if (params.dir == Direction::kOut) { - LOG(FATAL) << "AAAAA"; - } - } -#else - MSVertexColumnBuilder builder; - for (label_t output_vertex_label : output_vertex_set) { - builder.start_label(output_vertex_label); - if (params.dir == Direction::kBoth) { - LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; - RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + - std::to_string(params.dir)); - } else if (params.dir == Direction::kIn) { - for (auto& triplet : params.labels) { - if (triplet.dst_label == input_vertex_label && - triplet.src_label == output_vertex_label) { - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, output_vertex_label, triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_opt(nbr); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - }); - } - } - } else if (params.dir == Direction::kOut) { - LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; - RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + - std::to_string(params.dir)); - } - } -#endif - - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - } else { - if (params.dir == Direction::kOut) { - auto& casted_input_vertex_list = - *std::dynamic_pointer_cast(input_vertex_list); - MLVertexColumnBuilder builder; - foreach_vertex(casted_input_vertex_list, [&](size_t index, - label_t label, vid_t v) { - for (auto& triplet : params.labels) { - if (triplet.src_label == label) { - auto oe_iter = txn.GetOutEdgeIterator(label, v, triplet.dst_label, - triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_vertex( - std::make_pair(triplet.dst_label, nbr)); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - return ctx; - } else if (params.dir == Direction::kBoth) { - auto& casted_input_vertex_list = - *std::dynamic_pointer_cast(input_vertex_list); - MLVertexColumnBuilder builder; - foreach_vertex(casted_input_vertex_list, [&](size_t index, - label_t label, vid_t v) { - for (auto& triplet : params.labels) { - if (triplet.src_label == label) { - auto oe_iter = txn.GetOutEdgeIterator(label, v, triplet.dst_label, - triplet.edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - builder.push_back_vertex( - std::make_pair(triplet.dst_label, nbr)); - shuffle_offset.push_back(index); - oe_iter.Next(); - } - } - if (triplet.dst_label == label) { - auto ie_iter = txn.GetInEdgeIterator(label, v, triplet.src_label, - triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - builder.push_back_vertex( - std::make_pair(triplet.src_label, nbr)); - shuffle_offset.push_back(index); - ie_iter.Next(); - } - } - } - }); - ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); - return ctx; - } else { - LOG(ERROR) << "Unsupported edge expand direction: " - << static_cast(params.dir); - } - LOG(ERROR) << "edge expand vertex input multiple vertex label"; - RETURN_UNSUPPORTED_ERROR( - "edge expand vertex input multiple vertex label"); - } - } - - return ctx; -} - -bl::result EdgeExpand::expand_2d_vertex_without_predicate( - const ReadTransaction& txn, Context&& ctx, const EdgeExpandParams& params1, - const EdgeExpandParams& params2) { - std::shared_ptr input_vertex_list = - std::dynamic_pointer_cast(ctx.get(params1.v_tag)); - VertexColumnType input_vertex_list_type = - input_vertex_list->vertex_column_type(); - - std::vector shuffle_offset; - - if (params1.labels.size() == 1 && params2.labels.size() == 1) { - if (params1.dir == Direction::kOut && params2.dir == Direction::kOut) { - label_t d0_label = params1.labels[0].src_label; - label_t d1_label = params1.labels[0].dst_label; - label_t d2_label = params2.labels[0].dst_label; - label_t e0_label = params1.labels[0].edge_label; - label_t e1_label = params2.labels[0].edge_label; - - SLVertexColumnBuilder builder(d2_label); - - if (input_vertex_list_type == VertexColumnType::kSingle) { - auto casted_input_vertex_list = - std::dynamic_pointer_cast(input_vertex_list); - auto oe_csr0 = - txn.GetOutgoingSingleImmutableGraphView( - d0_label, d1_label, e0_label); - auto oe_csr1 = txn.GetOutgoingGraphView( - d1_label, d2_label, e1_label); - casted_input_vertex_list->foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - if (oe_csr0.exist(v)) { - auto& oe0 = oe_csr0.get_edge(v); - auto oe1_slice = oe_csr1.get_edges(oe0.neighbor); - for (auto& e : oe1_slice) { - builder.push_back_opt(e.neighbor); - shuffle_offset.push_back(index); - } - } - - // auto oe_iter0 = - // txn.GetOutEdgeIterator(d0_label, v, d1_label, e0_label); - // while (oe_iter0.IsValid()) { - // auto nbr = oe_iter0.GetNeighbor(); - // auto oe_iter1 = - // txn.GetOutEdgeIterator(d1_label, nbr, d2_label, - // e1_label); - // while (oe_iter1.IsValid()) { - // auto nbr2 = oe_iter1.GetNeighbor(); - // builder.push_back_opt(nbr2); - // shuffle_offset.push_back(index); - // oe_iter1.Next(); - // } - // oe_iter0.Next(); - // } - }); - - ctx.set_with_reshuffle(params2.alias, builder.finish(), shuffle_offset); - return ctx; - } - } - } - LOG(ERROR) << "Unsupported edge expand 2d vertex without predicate, " - << "params1.dir: " << static_cast(params1.dir) - << ", params2.dir: " << static_cast(params2.dir) - << ", params1.labels.size: " << params1.labels.size() - << ", params2.labels.size: " << params2.labels.size(); - RETURN_UNSUPPORTED_ERROR( - "Unsupported params for edge expand 2d vertex without predicate"); -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/edge_expand.h b/flex/engines/graph_db/runtime/common/operators/edge_expand.h index 7ad9dfd442fa..bd888b5c4379 100644 --- a/flex/engines/graph_db/runtime/common/operators/edge_expand.h +++ b/flex/engines/graph_db/runtime/common/operators/edge_expand.h @@ -38,8 +38,8 @@ struct EdgeExpandParams { class EdgeExpand { public: - template - static bl::result expand_edge(const ReadTransaction& txn, + template + static bl::result expand_edge(const GraphInterface& txn, Context&& ctx, const EdgeExpandParams& params, const PRED_T& pred) { @@ -51,7 +51,7 @@ class EdgeExpand { label_t output_vertex_label = params.labels[0].src_label; label_t edge_label = params.labels[0].edge_label; - auto& props = txn.schema().get_edge_properties( + const auto& props = txn.GetEdgePropertyTypes( params.labels[0].src_label, params.labels[0].dst_label, params.labels[0].edge_label); PropertyType pt = PropertyType::kEmpty; @@ -67,8 +67,9 @@ class EdgeExpand { foreach_vertex(input_vertex_list, [&](size_t index, label_t label, vid_t v) { + // TODO: Change the order of the src_label, dst_label auto ie_iter = txn.GetInEdgeIterator( - label, v, output_vertex_label, edge_label); + label, output_vertex_label, edge_label, v); while (ie_iter.IsValid()) { auto nbr = ie_iter.GetNeighbor(); if (pred(params.labels[0], nbr, v, ie_iter.GetData(), @@ -90,7 +91,7 @@ class EdgeExpand { label_t edge_label = params.labels[0].edge_label; label_t src_label = params.labels[0].src_label; - auto& props = txn.schema().get_edge_properties( + const auto& props = txn.GetEdgePropertyTypes( params.labels[0].src_label, params.labels[0].dst_label, params.labels[0].edge_label); PropertyType pt = PropertyType::kEmpty; @@ -110,7 +111,7 @@ class EdgeExpand { return; } auto oe_iter = txn.GetOutEdgeIterator( - label, v, output_vertex_label, edge_label); + label, output_vertex_label, edge_label, v); while (oe_iter.IsValid()) { auto nbr = oe_iter.GetNeighbor(); if (pred(params.labels[0], v, nbr, oe_iter.GetData(), @@ -136,7 +137,7 @@ class EdgeExpand { *std::dynamic_pointer_cast(ctx.get(params.v_tag)); std::vector> label_props; for (auto& triplet : params.labels) { - auto& props = txn.schema().get_edge_properties( + const auto& props = txn.GetEdgePropertyTypes( triplet.src_label, triplet.dst_label, triplet.edge_label); PropertyType pt = PropertyType::kEmpty; if (!props.empty()) { @@ -153,7 +154,7 @@ class EdgeExpand { auto& pt = label_prop.second; if (label == triplet.src_label) { auto oe_iter = txn.GetOutEdgeIterator( - label, v, triplet.dst_label, triplet.edge_label); + label, triplet.dst_label, triplet.edge_label, v); while (oe_iter.IsValid()) { auto nbr = oe_iter.GetNeighbor(); if (pred(triplet, v, nbr, oe_iter.GetData(), @@ -167,8 +168,8 @@ class EdgeExpand { } } if (label == triplet.dst_label) { - auto ie_iter = txn.GetInEdgeIterator( - label, v, triplet.src_label, triplet.edge_label); + auto ie_iter = txn.GetInEdgeIterator(label, triplet.src_label, + triplet.edge_label, v); while (ie_iter.IsValid()) { auto nbr = ie_iter.GetNeighbor(); if (pred(triplet, nbr, v, ie_iter.GetData(), Direction::kIn, @@ -190,7 +191,7 @@ class EdgeExpand { *std::dynamic_pointer_cast(ctx.get(params.v_tag)); std::vector> label_props; for (auto& triplet : params.labels) { - auto& props = txn.schema().get_edge_properties( + const auto& props = txn.GetEdgePropertyTypes( triplet.src_label, triplet.dst_label, triplet.edge_label); PropertyType pt = PropertyType::kEmpty; if (!props.empty()) { @@ -207,8 +208,8 @@ class EdgeExpand { auto& pt = label_prop.second; if (label != triplet.src_label) continue; - auto oe_iter = txn.GetOutEdgeIterator( - label, v, triplet.dst_label, triplet.edge_label); + auto oe_iter = txn.GetOutEdgeIterator(label, triplet.dst_label, + triplet.edge_label, v); while (oe_iter.IsValid()) { auto nbr = oe_iter.GetNeighbor(); if (pred(triplet, v, nbr, oe_iter.GetData(), Direction::kOut, @@ -231,15 +232,15 @@ class EdgeExpand { } } + template static bl::result expand_edge_without_predicate( - const ReadTransaction& txn, Context&& ctx, + const GraphInterface& txn, Context&& ctx, const EdgeExpandParams& params); - template - static bl::result expand_vertex(const ReadTransaction& txn, - Context&& ctx, - const EdgeExpandParams& params, - const PRED_T& pred) { + template + static bl::result expand_vertex( + const GraphInterface& txn, Context&& ctx, + const EdgeExpandParams& params, const PRED_T& pred) { std::shared_ptr input_vertex_list = std::dynamic_pointer_cast(ctx.get(params.v_tag)); VertexColumnType input_vertex_list_type = @@ -299,7 +300,7 @@ class EdgeExpand { casted_input_vertex_list->foreach_vertex( [&](size_t index, label_t label, vid_t v) { auto oe_iter = txn.GetOutEdgeIterator( - label, v, label, label_triplet.edge_label); + label, label, label_triplet.edge_label, v); while (oe_iter.IsValid()) { auto nbr = oe_iter.GetNeighbor(); if (pred(label_triplet, v, nbr, oe_iter.GetData(), @@ -310,7 +311,7 @@ class EdgeExpand { oe_iter.Next(); } auto ie_iter = txn.GetInEdgeIterator( - label, v, label, label_triplet.edge_label); + label, label, label_triplet.edge_label, v); while (ie_iter.IsValid()) { auto nbr = ie_iter.GetNeighbor(); if (pred(label_triplet, nbr, v, ie_iter.GetData(), @@ -330,7 +331,7 @@ class EdgeExpand { casted_input_vertex_list->foreach_vertex( [&](size_t index, label_t label, vid_t v) { auto ie_iter = txn.GetInEdgeIterator( - label, v, output_vertex_label, label_triplet.edge_label); + label, output_vertex_label, label_triplet.edge_label, v); while (ie_iter.IsValid()) { auto nbr = ie_iter.GetNeighbor(); if (pred(label_triplet, nbr, v, ie_iter.GetData(), @@ -376,7 +377,7 @@ class EdgeExpand { casted_input_vertex_list->foreach_vertex( [&](size_t index, label_t label, vid_t v) { auto ie_iter = txn.GetInEdgeIterator( - label, v, output_vertex_label, triplet.edge_label); + label, output_vertex_label, triplet.edge_label, v); while (ie_iter.IsValid()) { auto nbr = ie_iter.GetNeighbor(); if (pred(triplet, nbr, v, ie_iter.GetData(), @@ -411,15 +412,859 @@ class EdgeExpand { return ctx; } + template static bl::result expand_vertex_without_predicate( - const ReadTransaction& txn, Context&& ctx, + const GraphInterface& txn, Context&& ctx, const EdgeExpandParams& params); + template static bl::result expand_2d_vertex_without_predicate( - const ReadTransaction& txn, Context&& ctx, + const GraphInterface& txn, Context&& ctx, const EdgeExpandParams& params1, const EdgeExpandParams& params2); }; +template +static std::vector get_expand_label_set( + const GraphInterface& txn, const std::set& label_set, + const std::vector& labels, Direction dir) { + std::vector label_triplets; + if (dir == Direction::kOut) { + for (auto& triplet : labels) { + if (label_set.count(triplet.src_label)) { + label_triplets.emplace_back(triplet); + } + } + } else if (dir == Direction::kIn) { + for (auto& triplet : labels) { + if (label_set.count(triplet.dst_label)) { + label_triplets.emplace_back(triplet); + } + } + } else { + for (auto& triplet : labels) { + if (label_set.count(triplet.src_label) || + label_set.count(triplet.dst_label)) { + label_triplets.emplace_back(triplet); + } + } + } + return label_triplets; +} + +template +bl::result EdgeExpand::expand_edge_without_predicate( + const GraphInterface& txn, Context&& ctx, + const EdgeExpandParams& params) { + std::vector shuffle_offset; + + if (params.labels.size() == 1) { + if (params.dir == Direction::kIn) { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.v_tag)); + label_t output_vertex_label = params.labels[0].src_label; + label_t edge_label = params.labels[0].edge_label; + + const auto& props = txn.GetEdgePropertyTypes(params.labels[0].src_label, + params.labels[0].dst_label, + params.labels[0].edge_label); + PropertyType pt = PropertyType::kEmpty; + if (props.size() > 1) { + pt = PropertyType::kRecordView; + + } else if (!props.empty()) { + pt = props[0]; + } + + SDSLEdgeColumnBuilder builder(Direction::kIn, params.labels[0], pt, + props); + + label_t dst_label = params.labels[0].dst_label; + foreach_vertex(input_vertex_list, + [&](size_t index, label_t label, vid_t v) { + if (label != dst_label) { + return; + } + auto ie_iter = txn.GetInEdgeIterator( + label, output_vertex_label, edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + CHECK(ie_iter.GetData().type == pt) + << ie_iter.GetData().type << " " << pt; + builder.push_back_opt(nbr, v, ie_iter.GetData()); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + }); + + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + return ctx; + } else if (params.dir == Direction::kOut) { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.v_tag)); + label_t output_vertex_label = params.labels[0].dst_label; + label_t edge_label = params.labels[0].edge_label; + + const auto& props = txn.GetEdgePropertyTypes(params.labels[0].src_label, + params.labels[0].dst_label, + params.labels[0].edge_label); + PropertyType pt = PropertyType::kEmpty; + + if (!props.empty()) { + pt = props[0]; + } + if (props.size() > 1) { + pt = PropertyType::kRecordView; + } + + SDSLEdgeColumnBuilder builder(Direction::kOut, params.labels[0], pt, + props); + label_t src_label = params.labels[0].src_label; + foreach_vertex(input_vertex_list, + [&](size_t index, label_t label, vid_t v) { + if (label != src_label) { + return; + } + auto oe_iter = txn.GetOutEdgeIterator( + label, output_vertex_label, edge_label, v); + + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + CHECK(oe_iter.GetData().type == pt); + builder.push_back_opt(v, nbr, oe_iter.GetData()); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + }); + + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + return ctx; + } else { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.v_tag)); + const auto& props = txn.GetEdgePropertyTypes(params.labels[0].src_label, + params.labels[0].dst_label, + params.labels[0].edge_label); + PropertyType pt = PropertyType::kEmpty; + if (!props.empty()) { + pt = props[0]; + } + BDSLEdgeColumnBuilder builder(params.labels[0], pt); + foreach_vertex(input_vertex_list, [&](size_t index, label_t label, + vid_t v) { + if (label == params.labels[0].src_label) { + auto oe_iter = + txn.GetOutEdgeIterator(label, params.labels[0].dst_label, + params.labels[0].edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(v, nbr, oe_iter.GetData(), Direction::kOut); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + if (label == params.labels[0].dst_label) { + auto ie_iter = + txn.GetInEdgeIterator(label, params.labels[0].src_label, + params.labels[0].edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(nbr, v, ie_iter.GetData(), Direction::kIn); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + return ctx; + } + } else { + auto column = + std::dynamic_pointer_cast(ctx.get(params.v_tag)); + auto label_set = column->get_labels_set(); + auto labels = + get_expand_label_set(txn, label_set, params.labels, params.dir); + std::vector> label_props; + std::vector> props_vec; + for (auto& triplet : labels) { + const auto& props = txn.GetEdgePropertyTypes( + triplet.src_label, triplet.dst_label, triplet.edge_label); + PropertyType pt = PropertyType::kEmpty; + if (!props.empty()) { + pt = props[0]; + } + if (props.size() > 1) { + pt = PropertyType::kRecordView; + } + props_vec.emplace_back(props); + label_props.emplace_back(triplet, pt); + } + if (params.dir == Direction::kOut || params.dir == Direction::kIn) { + if (labels.size() == 1) { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.v_tag)); + if (params.dir == Direction::kOut) { + auto& triplet = labels[0]; + SDSLEdgeColumnBuilder builder(Direction::kOut, triplet, + label_props[0].second, props_vec[0]); + foreach_vertex( + input_vertex_list, [&](size_t index, label_t label, vid_t v) { + if (label == triplet.src_label) { + auto oe_iter = txn.GetOutEdgeIterator( + label, triplet.dst_label, triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(v, nbr, oe_iter.GetData()); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), + shuffle_offset); + return ctx; + } else if (params.dir == Direction::kIn) { + auto& triplet = labels[0]; + SDSLEdgeColumnBuilder builder(Direction::kIn, triplet, + label_props[0].second, props_vec[0]); + foreach_vertex( + input_vertex_list, [&](size_t index, label_t label, vid_t v) { + if (label == triplet.dst_label) { + auto ie_iter = txn.GetInEdgeIterator(label, triplet.src_label, + triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(nbr, v, ie_iter.GetData()); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), + shuffle_offset); + return ctx; + } + } else if (labels.size() > 1 || labels.size() == 0) { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.v_tag)); + + SDMLEdgeColumnBuilder builder(params.dir, label_props); + if (params.dir == Direction::kOut) { + foreach_vertex(input_vertex_list, [&](size_t index, label_t label, + vid_t v) { + for (auto& triplet : labels) { + if (triplet.src_label == label) { + if (params.dir == Direction::kOut) { + auto oe_iter = txn.GetOutEdgeIterator( + label, triplet.dst_label, triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(triplet, v, nbr, oe_iter.GetData()); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + } + } + }); + } else { + foreach_vertex(input_vertex_list, [&](size_t index, label_t label, + vid_t v) { + for (auto& triplet : labels) { + if (triplet.dst_label == label) { + if (params.dir == Direction::kIn) { + auto ie_iter = txn.GetInEdgeIterator(label, triplet.src_label, + triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(triplet, nbr, v, ie_iter.GetData()); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + } + } + }); + } + + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + return ctx; + } + } else if (params.dir == Direction::kBoth) { + if (labels.size() == 1) { + BDSLEdgeColumnBuilder builder(labels[0], label_props[0].second); + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.v_tag)); + foreach_vertex(input_vertex_list, [&](size_t index, label_t label, + vid_t v) { + if (label == labels[0].src_label) { + auto oe_iter = txn.GetOutEdgeIterator(label, labels[0].dst_label, + labels[0].edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(v, nbr, oe_iter.GetData(), Direction::kOut); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + if (label == labels[0].dst_label) { + auto ie_iter = txn.GetInEdgeIterator(label, labels[0].src_label, + labels[0].edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(nbr, v, ie_iter.GetData(), Direction::kIn); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + return ctx; + + } else { + BDMLEdgeColumnBuilder builder(label_props); + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.v_tag)); + foreach_vertex( + input_vertex_list, [&](size_t index, label_t label, vid_t v) { + for (auto& triplet : labels) { + if (triplet.src_label == label) { + auto oe_iter = txn.GetOutEdgeIterator( + label, triplet.dst_label, triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(triplet, v, nbr, oe_iter.GetData(), + Direction::kOut); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + if (triplet.dst_label == label) { + auto ie_iter = txn.GetInEdgeIterator(label, triplet.src_label, + triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(triplet, nbr, v, ie_iter.GetData(), + Direction::kIn); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + return ctx; + } + } + } + + LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; + RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + + std::to_string(params.dir)); +} + +template +bl::result EdgeExpand::expand_vertex_without_predicate( + const GraphInterface& txn, Context&& ctx, + const EdgeExpandParams& params) { + std::shared_ptr input_vertex_list = + std::dynamic_pointer_cast(ctx.get(params.v_tag)); + VertexColumnType input_vertex_list_type = + input_vertex_list->vertex_column_type(); + + std::set output_vertex_set; + const std::set& input_vertex_set = + input_vertex_list->get_labels_set(); + if (params.dir == Direction::kOut) { + for (auto& triplet : params.labels) { + if (input_vertex_set.find(triplet.src_label) != input_vertex_set.end()) { + output_vertex_set.insert(triplet.dst_label); + } + } + } else if (params.dir == Direction::kIn) { + for (auto& triplet : params.labels) { + if (input_vertex_set.find(triplet.dst_label) != input_vertex_set.end()) { + output_vertex_set.insert(triplet.src_label); + } + } + } else { + for (auto& triplet : params.labels) { + if (input_vertex_set.find(triplet.src_label) != input_vertex_set.end()) { + output_vertex_set.insert(triplet.dst_label); + } + if (input_vertex_set.find(triplet.dst_label) != input_vertex_set.end()) { + output_vertex_set.insert(triplet.src_label); + } + } + } + + // if (output_vertex_set.empty()) { + // LOG(FATAL) << "output vertex label set is empty..."; + // } + + std::vector shuffle_offset; + + if (output_vertex_set.size() <= 1) { + label_t output_vertex_label = *output_vertex_set.begin(); + SLVertexColumnBuilder builder(output_vertex_label); + + if (input_vertex_list_type == VertexColumnType::kSingle) { + auto casted_input_vertex_list = + std::dynamic_pointer_cast(input_vertex_list); + label_t input_vertex_label = casted_input_vertex_list->label(); + if (params.labels.size() == 1) { + auto& label_triplet = params.labels[0]; + if (params.dir == Direction::kBoth && + label_triplet.src_label == label_triplet.dst_label && + label_triplet.src_label == output_vertex_label && + output_vertex_label == input_vertex_label) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + auto oe_iter = txn.GetOutEdgeIterator( + label, label, label_triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + auto ie_iter = txn.GetInEdgeIterator( + label, label, label_triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), + shuffle_offset); + } else if (params.dir == Direction::kIn && + label_triplet.src_label == output_vertex_label && + label_triplet.dst_label == input_vertex_label) { + const auto& props = txn.GetEdgePropertyTypes( + label_triplet.src_label, label_triplet.dst_label, + label_triplet.edge_label); + if (props.empty()) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + auto iter = txn.GetInEdgeIterator( + label, output_vertex_label, label_triplet.edge_label, v); + while (iter.IsValid()) { + builder.push_back_opt(iter.GetNeighbor()); + shuffle_offset.push_back(index); + iter.Next(); + } + }); + } else if (props[0] == PropertyType::kDate) { + // also check csr mutability + // const TypedMutableCsrBase* csr = + // dynamic_cast*>( + // txn.graph().get_ie_csr(label_triplet.dst_label, + // label_triplet.src_label, + // label_triplet.edge_label)); + auto sub_graph = txn.template GetIncomingGraphView( + label_triplet.src_label, label_triplet.dst_label, + label_triplet.edge_label); + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + auto slice = sub_graph.GetEdges(v); + for (auto edge : slice) { + builder.push_back_opt(edge.GetNeighbor()); + shuffle_offset.push_back(index); + } + }); + } else { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + auto ie_iter = txn.GetInEdgeIterator( + label, output_vertex_label, label_triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + }); + } + // casted_input_vertex_list->foreach_vertex( + // [&](size_t index, label_t label, vid_t v) { + // auto ie_iter = txn.GetInEdgeIterator( + // label, v, output_vertex_label, + // label_triplet.edge_label); + // while (ie_iter.IsValid()) { + // auto nbr = ie_iter.GetNeighbor(); + // builder.push_back_opt(nbr); + // shuffle_offset.push_back(index); + // ie_iter.Next(); + // } + // }); + ctx.set_with_reshuffle(params.alias, builder.finish(), + shuffle_offset); + } else if (params.dir == Direction::kOut && + label_triplet.src_label == input_vertex_label && + label_triplet.dst_label == output_vertex_label) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + auto oe_iter = txn.GetOutEdgeIterator( + label, output_vertex_label, label_triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), + shuffle_offset); + } else { + LOG(ERROR) << "Unsupported edge expand direction"; + RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction"); + } + } else { + MLVertexColumnBuilder builder; + if (params.dir == Direction::kOut || params.dir == Direction::kIn) { + if (params.dir == Direction::kOut) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + for (auto& triplet : params.labels) { + if (triplet.src_label == label) { + auto oe_iter = txn.GetOutEdgeIterator( + label, triplet.dst_label, triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_vertex( + std::make_pair(triplet.dst_label, nbr)); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + } + }); + } else { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + for (auto& triplet : params.labels) { + if (triplet.dst_label == label) { + auto ie_iter = txn.GetInEdgeIterator( + label, triplet.src_label, triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_vertex( + std::make_pair(triplet.src_label, nbr)); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + } + }); + } + ctx.set_with_reshuffle(params.alias, builder.finish(), + shuffle_offset); + } + } + } else if (input_vertex_list_type == VertexColumnType::kMultiple) { + auto casted_input_vertex_list = + std::dynamic_pointer_cast(input_vertex_list); + if (params.dir == Direction::kBoth) { + LOG(ERROR) << "Unsupported edge expand direction"; + RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction"); + } else if (params.dir == Direction::kIn) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + for (auto& triplet : params.labels) { + if (triplet.dst_label == label) { + auto ie_iter = txn.GetInEdgeIterator(label, triplet.src_label, + triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + } else if (params.dir == Direction::kOut) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + for (auto& triplet : params.labels) { + if (triplet.src_label == label) { + auto oe_iter = txn.GetOutEdgeIterator( + label, triplet.dst_label, triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + } else { + LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; + RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + + std::to_string(params.dir)); + } + } else if (input_vertex_list_type == VertexColumnType::kMultiSegment) { + auto casted_input_vertex_list = + std::dynamic_pointer_cast(input_vertex_list); + if (params.dir == Direction::kBoth) { + LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; + RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + + std::to_string(params.dir)); + } else if (params.dir == Direction::kIn) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + for (auto& triplet : params.labels) { + if (triplet.dst_label == label) { + auto ie_iter = txn.GetInEdgeIterator(label, triplet.src_label, + triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + } else if (params.dir == Direction::kOut) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + for (auto& triplet : params.labels) { + if (triplet.src_label == label) { + auto oe_iter = txn.GetOutEdgeIterator( + label, triplet.dst_label, triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + } else { + LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; + RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + + std::to_string(params.dir)); + } + } else { + LOG(ERROR) << "unexpected input vertex list type"; + RETURN_UNSUPPORTED_ERROR("unexpected input vertex list type"); + } + } else { + if (input_vertex_list_type == VertexColumnType::kSingle) { + auto casted_input_vertex_list = + std::dynamic_pointer_cast(input_vertex_list); + label_t input_vertex_label = casted_input_vertex_list->label(); +#if 0 + MLVertexColumnBuilder builder; + for (label_t output_vertex_label : output_vertex_set) { + if (params.dir == Direction::kBoth) { + LOG(FATAL) << "AAAAA"; + } else if (params.dir == Direction::kIn) { + for (auto& triplet : params.labels) { + if (triplet.dst_label == input_vertex_label && + triplet.src_label == output_vertex_label) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + auto ie_iter = txn.GetInEdgeIterator( + label, output_vertex_label, triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_vertex( + std::make_pair(output_vertex_label, nbr)); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + }); + } + } + } else if (params.dir == Direction::kOut) { + LOG(FATAL) << "AAAAA"; + } + } +#else + MSVertexColumnBuilder builder; + for (label_t output_vertex_label : output_vertex_set) { + builder.start_label(output_vertex_label); + if (params.dir == Direction::kBoth) { + LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; + RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + + std::to_string(params.dir)); + } else if (params.dir == Direction::kIn) { + for (auto& triplet : params.labels) { + if (triplet.dst_label == input_vertex_label && + triplet.src_label == output_vertex_label) { + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + auto ie_iter = txn.GetInEdgeIterator( + label, output_vertex_label, triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_opt(nbr); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + }); + } + } + } else if (params.dir == Direction::kOut) { + LOG(ERROR) << "Unsupported edge expand direction: " << params.dir; + RETURN_UNSUPPORTED_ERROR("Unsupported edge expand direction" + + std::to_string(params.dir)); + } + } +#endif + + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + } else { + if (params.dir == Direction::kOut) { + auto& casted_input_vertex_list = + *std::dynamic_pointer_cast(input_vertex_list); + MLVertexColumnBuilder builder; + foreach_vertex(casted_input_vertex_list, [&](size_t index, + label_t label, vid_t v) { + for (auto& triplet : params.labels) { + if (triplet.src_label == label) { + auto oe_iter = txn.GetOutEdgeIterator(label, triplet.dst_label, + triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_vertex( + std::make_pair(triplet.dst_label, nbr)); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + return ctx; + } else if (params.dir == Direction::kBoth) { + auto& casted_input_vertex_list = + *std::dynamic_pointer_cast(input_vertex_list); + MLVertexColumnBuilder builder; + foreach_vertex(casted_input_vertex_list, [&](size_t index, + label_t label, vid_t v) { + for (auto& triplet : params.labels) { + if (triplet.src_label == label) { + auto oe_iter = txn.GetOutEdgeIterator(label, triplet.dst_label, + triplet.edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + builder.push_back_vertex( + std::make_pair(triplet.dst_label, nbr)); + shuffle_offset.push_back(index); + oe_iter.Next(); + } + } + if (triplet.dst_label == label) { + auto ie_iter = txn.GetInEdgeIterator(label, triplet.src_label, + triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + builder.push_back_vertex( + std::make_pair(triplet.src_label, nbr)); + shuffle_offset.push_back(index); + ie_iter.Next(); + } + } + } + }); + ctx.set_with_reshuffle(params.alias, builder.finish(), shuffle_offset); + return ctx; + } else { + LOG(ERROR) << "Unsupported edge expand direction: " + << static_cast(params.dir); + } + LOG(ERROR) << "edge expand vertex input multiple vertex label"; + RETURN_UNSUPPORTED_ERROR( + "edge expand vertex input multiple vertex label"); + } + } + + return ctx; +} + +template +bl::result EdgeExpand::expand_2d_vertex_without_predicate( + const GraphInterface& txn, Context&& ctx, + const EdgeExpandParams& params1, const EdgeExpandParams& params2) { + std::shared_ptr input_vertex_list = + std::dynamic_pointer_cast(ctx.get(params1.v_tag)); + VertexColumnType input_vertex_list_type = + input_vertex_list->vertex_column_type(); + + std::vector shuffle_offset; + + if (params1.labels.size() == 1 && params2.labels.size() == 1) { + if (params1.dir == Direction::kOut && params2.dir == Direction::kOut) { + label_t d0_label = params1.labels[0].src_label; + label_t d1_label = params1.labels[0].dst_label; + label_t d2_label = params2.labels[0].dst_label; + label_t e0_label = params1.labels[0].edge_label; + label_t e1_label = params2.labels[0].edge_label; + + SLVertexColumnBuilder builder(d2_label); + + if (input_vertex_list_type == VertexColumnType::kSingle) { + auto casted_input_vertex_list = + std::dynamic_pointer_cast(input_vertex_list); + auto oe_csr0 = txn.template GetOutgoingGraphView( + d0_label, d1_label, e0_label); + auto oe_csr1 = txn.template GetOutgoingGraphView( + d1_label, d2_label, e1_label); + casted_input_vertex_list->foreach_vertex( + [&](size_t index, label_t label, vid_t v) { + // NOTE: Previously we use SingleGraphView's Exist() method. + // For general graph view, we need to use GetEdges() method. + // if (oe_csr0.Exist(v)) { + // TODO(lexiao): Confirm the correctness of the following code. + for (auto oe0_edge : oe_csr0.GetEdges(v)) { + auto oe1_slice = oe_csr1.GetEdges(oe0_edge.neighbor); + for (auto& e : oe1_slice) { + builder.push_back_opt(e.neighbor); + shuffle_offset.push_back(index); + } + } + + // auto oe_iter0 = + // txn.GetOutEdgeIterator(d0_label, v, d1_label, e0_label); + // while (oe_iter0.IsValid()) { + // auto nbr = oe_iter0.GetNeighbor(); + // auto oe_iter1 = + // txn.GetOutEdgeIterator(d1_label, nbr, d2_label, + // e1_label); + // while (oe_iter1.IsValid()) { + // auto nbr2 = oe_iter1.GetNeighbor(); + // builder.push_back_opt(nbr2); + // shuffle_offset.push_back(index); + // oe_iter1.Next(); + // } + // oe_iter0.Next(); + // } + }); + + ctx.set_with_reshuffle(params2.alias, builder.finish(), shuffle_offset); + return ctx; + } + } + } + LOG(ERROR) << "Unsupported edge expand 2d vertex without predicate, " + << "params1.dir: " << static_cast(params1.dir) + << ", params2.dir: " << static_cast(params2.dir) + << ", params1.labels.size: " << params1.labels.size() + << ", params2.labels.size: " << params2.labels.size(); + RETURN_UNSUPPORTED_ERROR( + "Unsupported params for edge expand 2d vertex without predicate"); +} // namespace runtime + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/get_v.h b/flex/engines/graph_db/runtime/common/operators/get_v.h index 6a509c825631..803366490822 100644 --- a/flex/engines/graph_db/runtime/common/operators/get_v.h +++ b/flex/engines/graph_db/runtime/common/operators/get_v.h @@ -58,11 +58,10 @@ bl::result> extract_labels( } class GetV { public: - template - static bl::result get_vertex_from_edges(const ReadTransaction& txn, - Context&& ctx, - const GetVParams& params, - const PRED_T& pred) { + template + static bl::result get_vertex_from_edges( + const GraphInterface& txn, Context&& ctx, + const GetVParams& params, const PRED_T& pred) { std::vector shuffle_offset; auto col = ctx.get(params.tag); if (col->column_type() == ContextColumnType::kPath) { @@ -354,8 +353,8 @@ class GetV { std::to_string(static_cast(column->edge_column_type()))); } - template - static Context get_vertex_from_vertices(const ReadTransaction& txn, + template + static Context get_vertex_from_vertices(const GraphInterface& txn, Context&& ctx, const GetVParams& params, const PRED_T& pred) { diff --git a/flex/engines/graph_db/runtime/common/operators/intersect.cc b/flex/engines/graph_db/runtime/common/operators/intersect.cc deleted file mode 100644 index 458fb2a48fbd..000000000000 --- a/flex/engines/graph_db/runtime/common/operators/intersect.cc +++ /dev/null @@ -1,193 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/operators/intersect.h" -#include "flex/engines/graph_db/runtime/common/columns/edge_columns.h" -#include "flex/engines/graph_db/runtime/common/columns/value_columns.h" -#include "flex/engines/graph_db/runtime/common/columns/vertex_columns.h" - -namespace gs { - -namespace runtime { - -static void ensure_sorted(std::shared_ptr> idx_col, - std::shared_ptr val_col) { - auto& idx_col_ref = *idx_col; - size_t row_num = idx_col_ref.size(); - for (size_t k = 1; k < row_num; ++k) { - CHECK_GE(idx_col_ref.get_value(k), idx_col_ref.get_value(k - 1)); - } -} - -bl::result Intersect::intersect( - Context&& ctx, std::vector>&& ctxs, - int alias) { - std::vector>, - std::shared_ptr>> - cols; - for (auto& c : ctxs) { - auto& this_ctx = std::get<0>(c); - int idx_col = std::get<1>(c); - int value_col = std::get<2>(c); - cols.emplace_back( - std::dynamic_pointer_cast>(this_ctx.get(idx_col)), - this_ctx.get(value_col)); - } - for (auto& pair : cols) { - ensure_sorted(pair.first, pair.second); - } - if (cols.size() == 2) { - auto& idx_col0 = *cols[0].first; - auto& idx_col1 = *cols[1].first; - - size_t rn0 = idx_col0.size(); - size_t rn1 = idx_col1.size(); - - CHECK(cols[0].second->column_type() == cols[1].second->column_type()); - if (cols[0].second->column_type() == ContextColumnType::kVertex) { - auto vlist0_ptr = - std::dynamic_pointer_cast(cols[0].second); - auto vlist1_ptr = - std::dynamic_pointer_cast(cols[1].second); - if (vlist0_ptr->vertex_column_type() == VertexColumnType::kSingle && - vlist1_ptr->vertex_column_type() == VertexColumnType::kSingle) { - auto& vlist0 = *std::dynamic_pointer_cast(vlist0_ptr); - auto& vlist1 = *std::dynamic_pointer_cast(vlist1_ptr); - - std::vector shuffle_offsets; - SLVertexColumnBuilder builder(*vlist0.get_labels_set().begin()); - - size_t idx0 = 0, idx1 = 0; - std::set lhs_set; - while (idx0 < rn0 && idx1 < rn1) { - if (idx_col0.get_value(idx0) < idx_col1.get_value(idx1)) { - ++idx0; - } else if (idx_col0.get_value(idx0) > idx_col1.get_value(idx1)) { - ++idx1; - } else { - lhs_set.clear(); - size_t common_index = idx_col0.get_value(idx0); - while (idx_col0.get_value(idx0) == common_index) { - lhs_set.insert(vlist0.get_vertex(idx0).second); - ++idx0; - } - while (idx_col1.get_value(idx1) == common_index) { - vid_t cur_v = vlist1.get_vertex(idx1).second; - if (lhs_set.find(cur_v) != lhs_set.end()) { - shuffle_offsets.push_back(common_index); - builder.push_back_opt(cur_v); - } - ++idx1; - } - } - } - - ctx.set_with_reshuffle(alias, builder.finish(), shuffle_offsets); - return ctx; - } - } - } - LOG(ERROR) << "Currently we only support intersect on two columns"; - RETURN_NOT_IMPLEMENTED_ERROR( - "Currently we only support intersect on two columns"); -} - -static bl::result intersect_impl(std::vector&& ctxs, - int key) { - if (ctxs[0].get(key)->column_type() == ContextColumnType::kVertex) { - if (ctxs.size() == 2) { - auto& vlist0 = - *(std::dynamic_pointer_cast(ctxs[0].get(key))); - auto& vlist1 = - *(std::dynamic_pointer_cast(ctxs[1].get(key))); - auto& idx_col0 = ctxs[0].get_idx_col(); - auto& idx_col1 = ctxs[1].get_idx_col(); - std::vector offsets0(idx_col0.size()), offsets1(idx_col1.size()); - for (size_t k = 0; k < idx_col0.size(); ++k) { - offsets0[k] = k; - } - for (size_t k = 0; k < idx_col1.size(); ++k) { - offsets1[k] = k; - } - std::sort(offsets0.begin(), offsets0.end(), - [&idx_col0, &vlist0](size_t a, size_t b) { - if (idx_col0.get_value(a) == idx_col0.get_value(b)) { - return vlist0.get_vertex(a) < vlist0.get_vertex(b); - } - return idx_col0.get_value(a) < idx_col0.get_value(b); - }); - std::sort(offsets1.begin(), offsets1.end(), - [&idx_col1, &vlist1](size_t a, size_t b) { - if (idx_col1.get_value(a) == idx_col1.get_value(b)) { - return vlist1.get_vertex(a) < vlist1.get_vertex(b); - } - return idx_col1.get_value(a) < idx_col1.get_value(b); - }); - std::vector shuffle_offsets; - std::vector shuffle_offsets_1; - size_t idx0 = 0, idx1 = 0; - while (idx0 < idx_col0.size() && idx1 < idx_col1.size()) { - if (idx_col0.get_value(offsets0[idx0]) < - idx_col1.get_value(offsets1[idx1])) { - ++idx0; - } else if (idx_col0.get_value(offsets0[idx0]) > - idx_col1.get_value(offsets1[idx1])) { - ++idx1; - } else { - auto v0 = vlist0.get_vertex(offsets0[idx0]); - size_t pre_idx1 = idx1; - while (idx1 < idx_col1.size() && - idx_col1.get_value(offsets1[idx1]) == - idx_col0.get_value(offsets0[idx0])) { - auto v1 = vlist1.get_vertex(offsets1[idx1]); - if (v0 == v1) { - shuffle_offsets.push_back(offsets0[idx0]); - shuffle_offsets_1.push_back(offsets1[idx1]); - } else if (v0 < v1) { - break; - } else { - pre_idx1 = idx1; - } - ++idx1; - } - ++idx0; - idx1 = pre_idx1; - } - } - - ctxs[0].reshuffle(shuffle_offsets); - ctxs[1].reshuffle(shuffle_offsets_1); - ctxs[0].pop_idx_col(); - for (size_t i = 0; i < ctxs[1].col_num(); ++i) { - if (i >= ctxs[0].col_num() || ctxs[0].get(i) == nullptr) { - ctxs[0].set(i, ctxs[1].get(i)); - } - } - return ctxs[0]; - } - } - LOG(ERROR) << "Currently we only support intersect on vertex columns"; - RETURN_NOT_IMPLEMENTED_ERROR( - "Currently we only support intersect on vertex " - "columns"); -} - -bl::result Intersect::intersect(std::vector&& ctxs, int key) { - return intersect_impl(std::move(ctxs), key); -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/intersect.h b/flex/engines/graph_db/runtime/common/operators/intersect.h index 7c09e3d00324..e6c1ad73a667 100644 --- a/flex/engines/graph_db/runtime/common/operators/intersect.h +++ b/flex/engines/graph_db/runtime/common/operators/intersect.h @@ -35,6 +35,172 @@ class Intersect { static bl::result intersect(std::vector&& ctxs, int key); }; +static void ensure_sorted(std::shared_ptr> idx_col, + std::shared_ptr val_col) { + auto& idx_col_ref = *idx_col; + size_t row_num = idx_col_ref.size(); + for (size_t k = 1; k < row_num; ++k) { + CHECK_GE(idx_col_ref.get_value(k), idx_col_ref.get_value(k - 1)); + } +} + +bl::result Intersect::intersect( + Context&& ctx, std::vector>&& ctxs, + int alias) { + std::vector>, + std::shared_ptr>> + cols; + for (auto& c : ctxs) { + auto& this_ctx = std::get<0>(c); + int idx_col = std::get<1>(c); + int value_col = std::get<2>(c); + cols.emplace_back( + std::dynamic_pointer_cast>(this_ctx.get(idx_col)), + this_ctx.get(value_col)); + } + for (auto& pair : cols) { + ensure_sorted(pair.first, pair.second); + } + if (cols.size() == 2) { + auto& idx_col0 = *cols[0].first; + auto& idx_col1 = *cols[1].first; + + size_t rn0 = idx_col0.size(); + size_t rn1 = idx_col1.size(); + + CHECK(cols[0].second->column_type() == cols[1].second->column_type()); + if (cols[0].second->column_type() == ContextColumnType::kVertex) { + auto vlist0_ptr = + std::dynamic_pointer_cast(cols[0].second); + auto vlist1_ptr = + std::dynamic_pointer_cast(cols[1].second); + if (vlist0_ptr->vertex_column_type() == VertexColumnType::kSingle && + vlist1_ptr->vertex_column_type() == VertexColumnType::kSingle) { + auto& vlist0 = *std::dynamic_pointer_cast(vlist0_ptr); + auto& vlist1 = *std::dynamic_pointer_cast(vlist1_ptr); + + std::vector shuffle_offsets; + SLVertexColumnBuilder builder(*vlist0.get_labels_set().begin()); + + size_t idx0 = 0, idx1 = 0; + std::set lhs_set; + while (idx0 < rn0 && idx1 < rn1) { + if (idx_col0.get_value(idx0) < idx_col1.get_value(idx1)) { + ++idx0; + } else if (idx_col0.get_value(idx0) > idx_col1.get_value(idx1)) { + ++idx1; + } else { + lhs_set.clear(); + size_t common_index = idx_col0.get_value(idx0); + while (idx_col0.get_value(idx0) == common_index) { + lhs_set.insert(vlist0.get_vertex(idx0).second); + ++idx0; + } + while (idx_col1.get_value(idx1) == common_index) { + vid_t cur_v = vlist1.get_vertex(idx1).second; + if (lhs_set.find(cur_v) != lhs_set.end()) { + shuffle_offsets.push_back(common_index); + builder.push_back_opt(cur_v); + } + ++idx1; + } + } + } + + ctx.set_with_reshuffle(alias, builder.finish(), shuffle_offsets); + return ctx; + } + } + } + LOG(ERROR) << "Currently we only support intersect on two columns"; + RETURN_NOT_IMPLEMENTED_ERROR( + "Currently we only support intersect on two columns"); +} + +static bl::result intersect_impl(std::vector&& ctxs, + int key) { + if (ctxs[0].get(key)->column_type() == ContextColumnType::kVertex) { + if (ctxs.size() == 2) { + auto& vlist0 = + *(std::dynamic_pointer_cast(ctxs[0].get(key))); + auto& vlist1 = + *(std::dynamic_pointer_cast(ctxs[1].get(key))); + auto& idx_col0 = ctxs[0].get_idx_col(); + auto& idx_col1 = ctxs[1].get_idx_col(); + std::vector offsets0(idx_col0.size()), offsets1(idx_col1.size()); + for (size_t k = 0; k < idx_col0.size(); ++k) { + offsets0[k] = k; + } + for (size_t k = 0; k < idx_col1.size(); ++k) { + offsets1[k] = k; + } + std::sort(offsets0.begin(), offsets0.end(), + [&idx_col0, &vlist0](size_t a, size_t b) { + if (idx_col0.get_value(a) == idx_col0.get_value(b)) { + return vlist0.get_vertex(a) < vlist0.get_vertex(b); + } + return idx_col0.get_value(a) < idx_col0.get_value(b); + }); + std::sort(offsets1.begin(), offsets1.end(), + [&idx_col1, &vlist1](size_t a, size_t b) { + if (idx_col1.get_value(a) == idx_col1.get_value(b)) { + return vlist1.get_vertex(a) < vlist1.get_vertex(b); + } + return idx_col1.get_value(a) < idx_col1.get_value(b); + }); + std::vector shuffle_offsets; + std::vector shuffle_offsets_1; + size_t idx0 = 0, idx1 = 0; + while (idx0 < idx_col0.size() && idx1 < idx_col1.size()) { + if (idx_col0.get_value(offsets0[idx0]) < + idx_col1.get_value(offsets1[idx1])) { + ++idx0; + } else if (idx_col0.get_value(offsets0[idx0]) > + idx_col1.get_value(offsets1[idx1])) { + ++idx1; + } else { + auto v0 = vlist0.get_vertex(offsets0[idx0]); + size_t pre_idx1 = idx1; + while (idx1 < idx_col1.size() && + idx_col1.get_value(offsets1[idx1]) == + idx_col0.get_value(offsets0[idx0])) { + auto v1 = vlist1.get_vertex(offsets1[idx1]); + if (v0 == v1) { + shuffle_offsets.push_back(offsets0[idx0]); + shuffle_offsets_1.push_back(offsets1[idx1]); + } else if (v0 < v1) { + break; + } else { + pre_idx1 = idx1; + } + ++idx1; + } + ++idx0; + idx1 = pre_idx1; + } + } + + ctxs[0].reshuffle(shuffle_offsets); + ctxs[1].reshuffle(shuffle_offsets_1); + ctxs[0].pop_idx_col(); + for (size_t i = 0; i < ctxs[1].col_num(); ++i) { + if (i >= ctxs[0].col_num() || ctxs[0].get(i) == nullptr) { + ctxs[0].set(i, ctxs[1].get(i)); + } + } + return ctxs[0]; + } + } + LOG(ERROR) << "Currently we only support intersect on vertex columns"; + RETURN_NOT_IMPLEMENTED_ERROR( + "Currently we only support intersect on vertex " + "columns"); +} + +bl::result Intersect::intersect(std::vector&& ctxs, int key) { + return intersect_impl(std::move(ctxs), key); +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/join.cc b/flex/engines/graph_db/runtime/common/operators/join.cc deleted file mode 100644 index c6b46f4c10fd..000000000000 --- a/flex/engines/graph_db/runtime/common/operators/join.cc +++ /dev/null @@ -1,193 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/operators/join.h" -#include "flex/engines/graph_db/runtime/common/columns/vertex_columns.h" - -#include "flex/engines/graph_db/runtime/common/leaf_utils.h" - -namespace gs { - -namespace runtime { -bl::result Join::join(Context&& ctx, Context&& ctx2, - const JoinParams& params) { - CHECK(params.left_columns.size() == params.right_columns.size()) - << "Join columns size mismatch"; - if (params.join_type == JoinKind::kSemiJoin || - params.join_type == JoinKind::kAntiJoin) { - size_t right_size = ctx2.row_num(); - std::set right_set; - std::vector offset; - - for (size_t r_i = 0; r_i < right_size; ++r_i) { - std::vector bytes; - Encoder encoder(bytes); - for (size_t i = 0; i < params.right_columns.size(); i++) { - auto val = ctx2.get(params.right_columns[i])->get_elem(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - std::string cur(bytes.begin(), bytes.end()); - right_set.insert(cur); - } - - size_t left_size = ctx.row_num(); - for (size_t r_i = 0; r_i < left_size; ++r_i) { - std::vector bytes; - Encoder encoder(bytes); - for (size_t i = 0; i < params.left_columns.size(); i++) { - auto val = ctx.get(params.left_columns[i])->get_elem(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - std::string cur(bytes.begin(), bytes.end()); - if (params.join_type == JoinKind::kSemiJoin) { - if (right_set.find(cur) != right_set.end()) { - offset.push_back(r_i); - } - } else { - if (right_set.find(cur) == right_set.end()) { - offset.push_back(r_i); - } - } - } - ctx.reshuffle(offset); - return ctx; - } else if (params.join_type == JoinKind::kInnerJoin) { - size_t right_size = ctx2.row_num(); - std::map> right_set; - std::vector left_offset, right_offset; - - for (size_t r_i = 0; r_i < right_size; ++r_i) { - std::vector bytes; - Encoder encoder(bytes); - for (size_t i = 0; i < params.right_columns.size(); i++) { - auto val = ctx2.get(params.right_columns[i])->get_elem(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - std::string cur(bytes.begin(), bytes.end()); - right_set[cur].emplace_back(r_i); - } - - size_t left_size = ctx.row_num(); - for (size_t r_i = 0; r_i < left_size; ++r_i) { - std::vector bytes; - Encoder encoder(bytes); - for (size_t i = 0; i < params.left_columns.size(); i++) { - auto val = ctx.get(params.left_columns[i])->get_elem(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - std::string cur(bytes.begin(), bytes.end()); - if (right_set.find(cur) != right_set.end()) { - for (auto right : right_set[cur]) { - left_offset.push_back(r_i); - right_offset.push_back(right); - } - } - } - ctx.reshuffle(left_offset); - ctx2.reshuffle(right_offset); - Context ret; - for (size_t i = 0; i < ctx.col_num(); i++) { - ret.set(i, ctx.get(i)); - } - for (size_t i = 0; i < ctx2.col_num(); i++) { - if (i >= ret.col_num() || ret.get(i) == nullptr) { - ret.set(i, ctx2.get(i)); - } - } - return ret; - } else if (params.join_type == JoinKind::kLeftOuterJoin) { - size_t right_size = ctx2.row_num(); - auto right_col = ctx2.get(params.right_columns[0]); - // CHECK(right_col->column_type() == ContextColumnType::kVertex); - - std::map> right_map; - for (size_t r_i = 0; r_i < right_size; r_i++) { - std::vector bytes; - Encoder encoder(bytes); - for (size_t i = 0; i < params.right_columns.size(); i++) { - auto val = ctx2.get(params.right_columns[i])->get_elem(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - std::string cur(bytes.begin(), bytes.end()); - right_map[cur].emplace_back(r_i); - } - - std::vector> builders; - for (size_t i = 0; i < ctx2.col_num(); i++) { - if (std::find(params.right_columns.begin(), params.right_columns.end(), - i) == params.right_columns.end() && - ctx2.get(i) != nullptr) { - builders.emplace_back(ctx2.get(i)->optional_builder()); - } else { - builders.emplace_back(nullptr); - } - } - - std::vector offsets; - size_t left_size = ctx.row_num(); - for (size_t r_i = 0; r_i < left_size; r_i++) { - std::vector bytes; - Encoder encoder(bytes); - for (size_t i = 0; i < params.left_columns.size(); i++) { - auto val = ctx.get(params.left_columns[i])->get_elem(r_i); - val.encode_sig(val.type(), encoder); - encoder.put_byte('#'); - } - std::string cur(bytes.begin(), bytes.end()); - if (right_map.find(cur) == right_map.end()) { - for (size_t i = 0; i < ctx2.col_num(); i++) { - if (builders[i] != nullptr) { - builders[i]->push_back_null(); - } - } - offsets.emplace_back(r_i); - } else { - for (auto idx : right_map[cur]) { - for (size_t i = 0; i < ctx2.col_num(); i++) { - if (builders[i] != nullptr) { - builders[i]->push_back_elem(ctx2.get(i)->get_elem(idx)); - } - } - offsets.emplace_back(r_i); - } - } - } - ctx.reshuffle(offsets); - for (size_t i = 0; i < ctx2.col_num(); i++) { - if (builders[i] != nullptr) { - ctx.set(i, builders[i]->finish()); - } else if (i >= ctx.col_num()) { - ctx.set(i, nullptr); - } - } - - return ctx; - } else { - LOG(ERROR) << "Unsupported join type: " - << static_cast(params.join_type); - RETURN_NOT_IMPLEMENTED_ERROR( - "Join of type " + std::to_string(static_cast(params.join_type)) + - " is not supported"); - } - - return Context(); -} -} // namespace runtime -} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/common/operators/join.h b/flex/engines/graph_db/runtime/common/operators/join.h index cf6976b60d4c..a6478945f599 100644 --- a/flex/engines/graph_db/runtime/common/operators/join.h +++ b/flex/engines/graph_db/runtime/common/operators/join.h @@ -35,6 +35,175 @@ class Join { static bl::result join(Context&& ctx, Context&& ctx2, const JoinParams& params); }; + +bl::result Join::join(Context&& ctx, Context&& ctx2, + const JoinParams& params) { + CHECK(params.left_columns.size() == params.right_columns.size()) + << "Join columns size mismatch"; + if (params.join_type == JoinKind::kSemiJoin || + params.join_type == JoinKind::kAntiJoin) { + size_t right_size = ctx2.row_num(); + std::set right_set; + std::vector offset; + + for (size_t r_i = 0; r_i < right_size; ++r_i) { + std::vector bytes; + Encoder encoder(bytes); + for (size_t i = 0; i < params.right_columns.size(); i++) { + auto val = ctx2.get(params.right_columns[i])->get_elem(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + std::string cur(bytes.begin(), bytes.end()); + right_set.insert(cur); + } + + size_t left_size = ctx.row_num(); + for (size_t r_i = 0; r_i < left_size; ++r_i) { + std::vector bytes; + Encoder encoder(bytes); + for (size_t i = 0; i < params.left_columns.size(); i++) { + auto val = ctx.get(params.left_columns[i])->get_elem(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + std::string cur(bytes.begin(), bytes.end()); + if (params.join_type == JoinKind::kSemiJoin) { + if (right_set.find(cur) != right_set.end()) { + offset.push_back(r_i); + } + } else { + if (right_set.find(cur) == right_set.end()) { + offset.push_back(r_i); + } + } + } + ctx.reshuffle(offset); + return ctx; + } else if (params.join_type == JoinKind::kInnerJoin) { + size_t right_size = ctx2.row_num(); + std::map> right_set; + std::vector left_offset, right_offset; + + for (size_t r_i = 0; r_i < right_size; ++r_i) { + std::vector bytes; + Encoder encoder(bytes); + for (size_t i = 0; i < params.right_columns.size(); i++) { + auto val = ctx2.get(params.right_columns[i])->get_elem(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + std::string cur(bytes.begin(), bytes.end()); + right_set[cur].emplace_back(r_i); + } + + size_t left_size = ctx.row_num(); + for (size_t r_i = 0; r_i < left_size; ++r_i) { + std::vector bytes; + Encoder encoder(bytes); + for (size_t i = 0; i < params.left_columns.size(); i++) { + auto val = ctx.get(params.left_columns[i])->get_elem(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + std::string cur(bytes.begin(), bytes.end()); + if (right_set.find(cur) != right_set.end()) { + for (auto right : right_set[cur]) { + left_offset.push_back(r_i); + right_offset.push_back(right); + } + } + } + ctx.reshuffle(left_offset); + ctx2.reshuffle(right_offset); + Context ret; + for (size_t i = 0; i < ctx.col_num(); i++) { + ret.set(i, ctx.get(i)); + } + for (size_t i = 0; i < ctx2.col_num(); i++) { + if (i >= ret.col_num() || ret.get(i) == nullptr) { + ret.set(i, ctx2.get(i)); + } + } + return ret; + } else if (params.join_type == JoinKind::kLeftOuterJoin) { + size_t right_size = ctx2.row_num(); + auto right_col = ctx2.get(params.right_columns[0]); + // CHECK(right_col->column_type() == ContextColumnType::kVertex); + + std::map> right_map; + for (size_t r_i = 0; r_i < right_size; r_i++) { + std::vector bytes; + Encoder encoder(bytes); + for (size_t i = 0; i < params.right_columns.size(); i++) { + auto val = ctx2.get(params.right_columns[i])->get_elem(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + std::string cur(bytes.begin(), bytes.end()); + right_map[cur].emplace_back(r_i); + } + + std::vector> builders; + for (size_t i = 0; i < ctx2.col_num(); i++) { + if (std::find(params.right_columns.begin(), params.right_columns.end(), + i) == params.right_columns.end() && + ctx2.get(i) != nullptr) { + builders.emplace_back(ctx2.get(i)->optional_builder()); + } else { + builders.emplace_back(nullptr); + } + } + + std::vector offsets; + size_t left_size = ctx.row_num(); + for (size_t r_i = 0; r_i < left_size; r_i++) { + std::vector bytes; + Encoder encoder(bytes); + for (size_t i = 0; i < params.left_columns.size(); i++) { + auto val = ctx.get(params.left_columns[i])->get_elem(r_i); + val.encode_sig(val.type(), encoder); + encoder.put_byte('#'); + } + std::string cur(bytes.begin(), bytes.end()); + if (right_map.find(cur) == right_map.end()) { + for (size_t i = 0; i < ctx2.col_num(); i++) { + if (builders[i] != nullptr) { + builders[i]->push_back_null(); + } + } + offsets.emplace_back(r_i); + } else { + for (auto idx : right_map[cur]) { + for (size_t i = 0; i < ctx2.col_num(); i++) { + if (builders[i] != nullptr) { + builders[i]->push_back_elem(ctx2.get(i)->get_elem(idx)); + } + } + offsets.emplace_back(r_i); + } + } + } + ctx.reshuffle(offsets); + for (size_t i = 0; i < ctx2.col_num(); i++) { + if (builders[i] != nullptr) { + ctx.set(i, builders[i]->finish()); + } else if (i >= ctx.col_num()) { + ctx.set(i, nullptr); + } + } + + return ctx; + } else { + LOG(ERROR) << "Unsupported join type: " + << static_cast(params.join_type); + RETURN_NOT_IMPLEMENTED_ERROR( + "Join of type " + std::to_string(static_cast(params.join_type)) + + " is not supported"); + } + + return Context(); +} } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/order_by.h b/flex/engines/graph_db/runtime/common/operators/order_by.h index 22c5eaae44cb..6035cfcfdd14 100644 --- a/flex/engines/graph_db/runtime/common/operators/order_by.h +++ b/flex/engines/graph_db/runtime/common/operators/order_by.h @@ -156,8 +156,7 @@ typename ValueTypeExtractor>::type invokeTuple( class OrderBy { public: template - static void order_by_with_limit(const ReadTransaction& txn, Context& ctx, - const Comparer& cmp, size_t low, + static void order_by_with_limit(Context& ctx, const Comparer& cmp, size_t low, size_t high) { if (low == 0 && high >= ctx.row_num()) { std::vector offsets; @@ -193,7 +192,7 @@ class OrderBy { } template - static void order_by_with_limit_beta(const ReadTransaction& txn, Context& ctx, + static void order_by_with_limit_beta(Context& ctx, const std::tuple& keys, size_t low, size_t high) { size_t row_num = ctx.row_num(); diff --git a/flex/engines/graph_db/runtime/common/operators/path_expand.cc b/flex/engines/graph_db/runtime/common/operators/path_expand.cc deleted file mode 100644 index 56d1a4928dda..000000000000 --- a/flex/engines/graph_db/runtime/common/operators/path_expand.cc +++ /dev/null @@ -1,399 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/operators/path_expand.h" - -namespace gs { - -namespace runtime { - -bl::result PathExpand::edge_expand_v(const ReadTransaction& txn, - Context&& ctx, - const PathExpandParams& params) { - std::vector shuffle_offset; - if (params.labels.size() == 1) { - if (params.dir == Direction::kOut) { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.start_tag)); - label_t output_vertex_label = params.labels[0].dst_label; - label_t edge_label = params.labels[0].edge_label; - SLVertexColumnBuilder builder(output_vertex_label); - - std::vector input; - std::vector output; - input_vertex_list.foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - int depth = 0; - input.clear(); - output.clear(); - input.push_back(v); - while (depth < params.hop_upper && !input.empty()) { - if (depth >= params.hop_lower) { - for (auto u : input) { - builder.push_back_opt(u); - shuffle_offset.push_back(index); - - auto oe_iter = txn.GetOutEdgeIterator( - label, u, output_vertex_label, edge_label); - while (oe_iter.IsValid()) { - output.push_back(oe_iter.GetNeighbor()); - oe_iter.Next(); - } - } - } else { - for (auto u : input) { - auto oe_iter = txn.GetOutEdgeIterator( - label, u, output_vertex_label, edge_label); - while (oe_iter.IsValid()) { - output.push_back(oe_iter.GetNeighbor()); - oe_iter.Next(); - } - } - } - ++depth; - input.clear(); - std::swap(input, output); - } - }); - - ctx.set_with_reshuffle_beta(params.alias, builder.finish(), - shuffle_offset, params.keep_cols); - return ctx; - } else if (params.dir == Direction::kBoth && - params.labels[0].src_label == params.labels[0].dst_label) { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.start_tag)); - label_t output_vertex_label = params.labels[0].dst_label; - label_t edge_label = params.labels[0].edge_label; - - SLVertexColumnBuilder builder(output_vertex_label); - - std::vector> input; - std::vector> output; - std::set exclude; - CHECK_GE(params.hop_lower, 0); - CHECK_GE(params.hop_upper, params.hop_lower); - if (params.hop_lower == 0) { - RETURN_BAD_REQUEST_ERROR("hop_lower should be greater than 0"); - } else { - if (params.hop_upper == 1) { - RETURN_BAD_REQUEST_ERROR("hop_upper should be greater than 1"); - } else { - input_vertex_list.foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - output.emplace_back(index, v); - }); - } - int depth = 0; - while (depth < params.hop_upper) { - input.clear(); - std::swap(input, output); - - if (depth >= params.hop_lower) { - for (auto& pair : input) { - builder.push_back_opt(pair.second); - shuffle_offset.push_back(pair.first); - } - } - - if (depth + 1 >= params.hop_upper) { - break; - } - - auto label = params.labels[0].src_label; - for (auto& pair : input) { - auto index = pair.first; - auto v = pair.second; - auto oe_iter = txn.GetOutEdgeIterator(label, v, output_vertex_label, - edge_label); - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - if (exclude.find(nbr) == exclude.end()) { - output.emplace_back(index, nbr); - } - oe_iter.Next(); - } - - auto ie_iter = txn.GetInEdgeIterator(label, v, output_vertex_label, - edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - if (exclude.find(nbr) == exclude.end()) { - output.emplace_back(index, nbr); - } - ie_iter.Next(); - } - } - - ++depth; - } - } - ctx.set_with_reshuffle_beta(params.alias, builder.finish(), - shuffle_offset, params.keep_cols); - return ctx; - } - } else { - if (params.dir == Direction::kOut) { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.start_tag)); - std::set labels; - for (auto& label : params.labels) { - labels.emplace(label.dst_label); - } - - MLVertexColumnBuilder builder(labels); - std::vector> input; - std::vector> output; - foreach_vertex(input_vertex_list, - [&](size_t index, label_t label, vid_t v) { - output.emplace_back(label, v, index); - }); - int depth = 0; - while (depth < params.hop_upper) { - input.clear(); - std::swap(input, output); - if (depth >= params.hop_lower) { - for (auto& tuple : input) { - builder.push_back_vertex( - std::make_pair(std::get<0>(tuple), std::get<1>(tuple))); - shuffle_offset.push_back(std::get<2>(tuple)); - } - } - - if (depth + 1 >= params.hop_upper) { - break; - } - - for (auto& tuple : input) { - auto label = std::get<0>(tuple); - auto v = std::get<1>(tuple); - auto index = std::get<2>(tuple); - for (auto& label_triplet : params.labels) { - if (label_triplet.src_label == label) { - auto oe_iter = txn.GetOutEdgeIterator(label_triplet.src_label, v, - label_triplet.dst_label, - label_triplet.edge_label); - - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - output.emplace_back(label_triplet.dst_label, nbr, index); - oe_iter.Next(); - } - } - } - } - ++depth; - } - ctx.set_with_reshuffle_beta(params.alias, builder.finish(), - shuffle_offset, params.keep_cols); - return ctx; - } else if (params.dir == Direction::kBoth) { - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.start_tag)); - std::set labels; - for (auto& label : params.labels) { - labels.emplace(label.dst_label); - } - - MLVertexColumnBuilder builder(labels); - std::vector> input; - std::vector> output; - input_vertex_list.foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - output.emplace_back(label, v, index); - }); - int depth = 0; - while (depth < params.hop_upper) { - input.clear(); - std::swap(input, output); - if (depth >= params.hop_lower) { - for (auto& tuple : input) { - builder.push_back_vertex( - std::make_pair(std::get<0>(tuple), std::get<1>(tuple))); - shuffle_offset.push_back(std::get<2>(tuple)); - } - } - - if (depth + 1 >= params.hop_upper) { - break; - } - - for (auto& tuple : input) { - auto label = std::get<0>(tuple); - auto v = std::get<1>(tuple); - auto index = std::get<2>(tuple); - for (auto& label_triplet : params.labels) { - if (label_triplet.src_label == label) { - auto oe_iter = txn.GetOutEdgeIterator(label_triplet.src_label, v, - label_triplet.dst_label, - label_triplet.edge_label); - - while (oe_iter.IsValid()) { - auto nbr = oe_iter.GetNeighbor(); - output.emplace_back(label_triplet.dst_label, nbr, index); - oe_iter.Next(); - } - } - if (label_triplet.dst_label == label) { - auto ie_iter = txn.GetInEdgeIterator(label_triplet.dst_label, v, - label_triplet.src_label, - label_triplet.edge_label); - while (ie_iter.IsValid()) { - auto nbr = ie_iter.GetNeighbor(); - output.emplace_back(label_triplet.src_label, nbr, index); - ie_iter.Next(); - } - } - } - } - depth++; - } - ctx.set_with_reshuffle_beta(params.alias, builder.finish(), - shuffle_offset, params.keep_cols); - return ctx; - } else { - LOG(ERROR) << "Not implemented yet"; - RETURN_NOT_IMPLEMENTED_ERROR("Not implemented yet for direction in"); - } - } - return ctx; -} - -bl::result PathExpand::edge_expand_p(const ReadTransaction& txn, - Context&& ctx, - const PathExpandParams& params) { - std::vector shuffle_offset; - auto& input_vertex_list = - *std::dynamic_pointer_cast(ctx.get(params.start_tag)); - auto label_sets = input_vertex_list.get_labels_set(); - auto labels = params.labels; - auto dir = params.dir; - std::vector, size_t>> input; - std::vector, size_t>> output; - std::vector> path_impls; - - GeneralPathColumnBuilder builder; - if (dir == Direction::kOut) { - foreach_vertex(input_vertex_list, - [&](size_t index, label_t label, vid_t v) { - auto p = PathImpl::make_path_impl(label, v); - input.emplace_back(p, index); - }); - int depth = 0; - while (depth < params.hop_upper) { - output.clear(); - if (depth >= params.hop_lower) { - for (auto& [path, index] : input) { - builder.push_back_opt(Path::make_path(path)); - path_impls.emplace_back(path); - shuffle_offset.push_back(index); - } - } - if (depth + 1 >= params.hop_upper) { - break; - } - - for (auto& [path, index] : input) { - auto end = path->get_end(); - for (auto& label_triplet : labels) { - if (label_triplet.src_label == end.first) { - auto oe_iter = txn.GetOutEdgeIterator(end.first, end.second, - label_triplet.dst_label, - label_triplet.edge_label); - while (oe_iter.IsValid()) { - std::shared_ptr new_path = - path->expand(label_triplet.dst_label, oe_iter.GetNeighbor()); - output.emplace_back(new_path, index); - oe_iter.Next(); - } - } - } - } - - input.clear(); - std::swap(input, output); - ++depth; - } - builder.set_path_impls(path_impls); - ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, - params.keep_cols); - - return ctx; - } else if (dir == Direction::kBoth) { - foreach_vertex(input_vertex_list, - [&](size_t index, label_t label, vid_t v) { - auto p = PathImpl::make_path_impl(label, v); - input.emplace_back(p, index); - }); - int depth = 0; - while (depth < params.hop_upper) { - output.clear(); - if (depth >= params.hop_lower) { - for (auto& [path, index] : input) { - builder.push_back_opt(Path::make_path(path)); - path_impls.emplace_back(path); - shuffle_offset.push_back(index); - } - } - if (depth + 1 >= params.hop_upper) { - break; - } - - for (auto& [path, index] : input) { - auto end = path->get_end(); - for (auto& label_triplet : labels) { - if (label_triplet.src_label == end.first) { - auto oe_iter = txn.GetOutEdgeIterator(end.first, end.second, - label_triplet.dst_label, - label_triplet.edge_label); - while (oe_iter.IsValid()) { - auto new_path = - path->expand(label_triplet.dst_label, oe_iter.GetNeighbor()); - output.emplace_back(new_path, index); - oe_iter.Next(); - } - } - if (label_triplet.dst_label == end.first) { - auto ie_iter = txn.GetInEdgeIterator(end.first, end.second, - label_triplet.src_label, - label_triplet.edge_label); - while (ie_iter.IsValid()) { - auto new_path = - path->expand(label_triplet.src_label, ie_iter.GetNeighbor()); - output.emplace_back(new_path, index); - ie_iter.Next(); - } - } - } - } - - input.clear(); - std::swap(input, output); - ++depth; - } - builder.set_path_impls(path_impls); - ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, - params.keep_cols); - return ctx; - } else { - LOG(ERROR) << "Not implemented yet"; - RETURN_NOT_IMPLEMENTED_ERROR("Not implemented yet for direction in"); - } - return ctx; -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/path_expand.h b/flex/engines/graph_db/runtime/common/operators/path_expand.h index b89b76cc7019..7bf7ad23a854 100644 --- a/flex/engines/graph_db/runtime/common/operators/path_expand.h +++ b/flex/engines/graph_db/runtime/common/operators/path_expand.h @@ -44,24 +44,22 @@ class PathExpand { public: // PathExpand(expandOpt == Vertex && alias == -1 && resultOpt == END_V) + // GetV(opt == END) - static bl::result edge_expand_v(const ReadTransaction& txn, - Context&& ctx, + template + static bl::result edge_expand_v(const GraphInterface& txn, Context&& ctx, const PathExpandParams& params); - static bl::result edge_expand_p(const ReadTransaction& txn, - Context&& ctx, + template + static bl::result edge_expand_p(const GraphInterface& txn, Context&& ctx, const PathExpandParams& params); - template - static bl::result edge_expand_v_pred(const ReadTransaction& txn, - Context&& ctx, - const PathExpandParams& params, + template + static bl::result edge_expand_v_pred(const GraphInterface& txn, + Context&& ctx, const PathExpandParams& params, const PRED_T& pred) { std::vector shuffle_offset; - if (params.labels.size() == 1 && - params.labels[0].src_label == params.labels[0].dst_label) { + if (params.labels.size() == 1 && params.labels[0].src_label == params.labels[0].dst_label) { if (params.dir == Direction::kOut) { - auto& input_vertex_list = *std::dynamic_pointer_cast( - ctx.get(params.start_tag)); + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.start_tag)); label_t output_vertex_label = params.labels[0].dst_label; label_t edge_label = params.labels[0].edge_label; label_t vertex_label = params.labels[0].src_label; @@ -85,7 +83,7 @@ class PathExpand { } auto oe_iter = txn.GetOutEdgeIterator( - label, u, output_vertex_label, edge_label); + label, output_vertex_label, edge_label, u); while (oe_iter.IsValid()) { output.push_back(oe_iter.GetNeighbor()); oe_iter.Next(); @@ -94,7 +92,7 @@ class PathExpand { } else { for (auto u : input) { auto oe_iter = txn.GetOutEdgeIterator( - label, u, output_vertex_label, edge_label); + label, output_vertex_label, edge_label, u); while (oe_iter.IsValid()) { output.push_back(oe_iter.GetNeighbor()); oe_iter.Next(); @@ -110,12 +108,10 @@ class PathExpand { std::vector> input; std::vector> output; input_vertex_list.foreach_vertex( - [&](size_t index, label_t label, vid_t v) { - output.emplace_back(index, v); - }); + [&](size_t index, label_t label, vid_t v) { output.emplace_back(index, v); }); int depth = 0; - auto oe_csr = txn.GetOutgoingSingleImmutableGraphView( - vertex_label, vertex_label, edge_label); + auto oe_csr = txn.template GetOutgoingGraphView(vertex_label, + vertex_label, edge_label); while (depth < params.hop_upper && !output.empty()) { input.clear(); std::swap(input, output); @@ -132,9 +128,11 @@ class PathExpand { for (auto& pair : input) { auto index = pair.first; auto v = pair.second; - if (oe_csr.exist(v)) { - output.emplace_back(index, oe_csr.get_edge(v).neighbor); + // TODO(lexiao): confirm the correctness of the following code + for (auto edge : oe_csr.GetEdges(v)) { + output.emplace_back(index, edge.neighbor); } + // auto oe_iter = txn.GetOutEdgeIterator( // vertex_label, v, output_vertex_label, edge_label); // while (oe_iter.IsValid()) { @@ -148,18 +146,363 @@ class PathExpand { } #endif - ctx.set_with_reshuffle_beta(params.alias, builder.finish(), - shuffle_offset, params.keep_cols); + ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, + params.keep_cols); return ctx; } } - RETURN_UNSUPPORTED_ERROR( - "Unsupported path expand. Currently only support " - "single edge label expand with src_label = dst_label."); + RETURN_UNSUPPORTED_ERROR("Unsupported path expand. Currently only support " + "single edge label expand with src_label = dst_label."); return ctx; } }; +template +bl::result PathExpand::edge_expand_v(const GraphInterface& txn, Context&& ctx, + const PathExpandParams& params) { + std::vector shuffle_offset; + if (params.labels.size() == 1) { + if (params.dir == Direction::kOut) { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.start_tag)); + label_t output_vertex_label = params.labels[0].dst_label; + label_t edge_label = params.labels[0].edge_label; + SLVertexColumnBuilder builder(output_vertex_label); + + std::vector input; + std::vector output; + input_vertex_list.foreach_vertex([&](size_t index, label_t label, vid_t v) { + int depth = 0; + input.clear(); + output.clear(); + input.push_back(v); + while (depth < params.hop_upper && !input.empty()) { + if (depth >= params.hop_lower) { + for (auto u : input) { + builder.push_back_opt(u); + shuffle_offset.push_back(index); + + auto oe_iter = txn.GetOutEdgeIterator(label, output_vertex_label, edge_label, u); + while (oe_iter.IsValid()) { + output.push_back(oe_iter.GetNeighbor()); + oe_iter.Next(); + } + } + } else { + for (auto u : input) { + auto oe_iter = txn.GetOutEdgeIterator(label, output_vertex_label, edge_label, u); + while (oe_iter.IsValid()) { + output.push_back(oe_iter.GetNeighbor()); + oe_iter.Next(); + } + } + } + ++depth; + input.clear(); + std::swap(input, output); + } + }); + + ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, params.keep_cols); + return ctx; + } else if (params.dir == Direction::kBoth && + params.labels[0].src_label == params.labels[0].dst_label) { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.start_tag)); + label_t output_vertex_label = params.labels[0].dst_label; + label_t edge_label = params.labels[0].edge_label; + + SLVertexColumnBuilder builder(output_vertex_label); + + std::vector> input; + std::vector> output; + std::set exclude; + CHECK_GE(params.hop_lower, 0); + CHECK_GE(params.hop_upper, params.hop_lower); + if (params.hop_lower == 0) { + RETURN_BAD_REQUEST_ERROR("hop_lower should be greater than 0"); + } else { + if (params.hop_upper == 1) { + RETURN_BAD_REQUEST_ERROR("hop_upper should be greater than 1"); + } else { + input_vertex_list.foreach_vertex( + [&](size_t index, label_t label, vid_t v) { output.emplace_back(index, v); }); + } + int depth = 0; + while (depth < params.hop_upper) { + input.clear(); + std::swap(input, output); + + if (depth >= params.hop_lower) { + for (auto& pair : input) { + builder.push_back_opt(pair.second); + shuffle_offset.push_back(pair.first); + } + } + + if (depth + 1 >= params.hop_upper) { + break; + } + + auto label = params.labels[0].src_label; + for (auto& pair : input) { + auto index = pair.first; + auto v = pair.second; + auto oe_iter = txn.GetOutEdgeIterator(label, output_vertex_label, edge_label, v); + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + if (exclude.find(nbr) == exclude.end()) { + output.emplace_back(index, nbr); + } + oe_iter.Next(); + } + + auto ie_iter = txn.GetInEdgeIterator(label, output_vertex_label, edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + if (exclude.find(nbr) == exclude.end()) { + output.emplace_back(index, nbr); + } + ie_iter.Next(); + } + } + + ++depth; + } + } + ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, params.keep_cols); + return ctx; + } + } else { + if (params.dir == Direction::kOut) { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.start_tag)); + std::set labels; + for (auto& label : params.labels) { + labels.emplace(label.dst_label); + } + + MLVertexColumnBuilder builder(labels); + std::vector> input; + std::vector> output; + foreach_vertex(input_vertex_list, [&](size_t index, label_t label, vid_t v) { + output.emplace_back(label, v, index); + }); + int depth = 0; + while (depth < params.hop_upper) { + input.clear(); + std::swap(input, output); + if (depth >= params.hop_lower) { + for (auto& tuple : input) { + builder.push_back_vertex(std::make_pair(std::get<0>(tuple), std::get<1>(tuple))); + shuffle_offset.push_back(std::get<2>(tuple)); + } + } + + if (depth + 1 >= params.hop_upper) { + break; + } + + for (auto& tuple : input) { + auto label = std::get<0>(tuple); + auto v = std::get<1>(tuple); + auto index = std::get<2>(tuple); + for (auto& label_triplet : params.labels) { + if (label_triplet.src_label == label) { + auto oe_iter = txn.GetOutEdgeIterator( + label_triplet.src_label, label_triplet.dst_label, label_triplet.edge_label, v); + + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + output.emplace_back(label_triplet.dst_label, nbr, index); + oe_iter.Next(); + } + } + } + } + ++depth; + } + ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, params.keep_cols); + return ctx; + } else if (params.dir == Direction::kBoth) { + auto& input_vertex_list = + *std::dynamic_pointer_cast(ctx.get(params.start_tag)); + std::set labels; + for (auto& label : params.labels) { + labels.emplace(label.dst_label); + } + + MLVertexColumnBuilder builder(labels); + std::vector> input; + std::vector> output; + input_vertex_list.foreach_vertex( + [&](size_t index, label_t label, vid_t v) { output.emplace_back(label, v, index); }); + int depth = 0; + while (depth < params.hop_upper) { + input.clear(); + std::swap(input, output); + if (depth >= params.hop_lower) { + for (auto& tuple : input) { + builder.push_back_vertex(std::make_pair(std::get<0>(tuple), std::get<1>(tuple))); + shuffle_offset.push_back(std::get<2>(tuple)); + } + } + + if (depth + 1 >= params.hop_upper) { + break; + } + + for (auto& tuple : input) { + auto label = std::get<0>(tuple); + auto v = std::get<1>(tuple); + auto index = std::get<2>(tuple); + for (auto& label_triplet : params.labels) { + if (label_triplet.src_label == label) { + auto oe_iter = txn.GetOutEdgeIterator( + label_triplet.src_label, label_triplet.dst_label, label_triplet.edge_label, v); + + while (oe_iter.IsValid()) { + auto nbr = oe_iter.GetNeighbor(); + output.emplace_back(label_triplet.dst_label, nbr, index); + oe_iter.Next(); + } + } + if (label_triplet.dst_label == label) { + auto ie_iter = txn.GetInEdgeIterator(label_triplet.dst_label, label_triplet.src_label, + label_triplet.edge_label, v); + while (ie_iter.IsValid()) { + auto nbr = ie_iter.GetNeighbor(); + output.emplace_back(label_triplet.src_label, nbr, index); + ie_iter.Next(); + } + } + } + } + depth++; + } + ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, params.keep_cols); + return ctx; + } else { + LOG(ERROR) << "Not implemented yet"; + RETURN_NOT_IMPLEMENTED_ERROR("Not implemented yet for direction in"); + } + } + return ctx; +} + +template +bl::result PathExpand::edge_expand_p(const GraphInterface& txn, Context&& ctx, + const PathExpandParams& params) { + std::vector shuffle_offset; + auto& input_vertex_list = *std::dynamic_pointer_cast(ctx.get(params.start_tag)); + auto label_sets = input_vertex_list.get_labels_set(); + auto labels = params.labels; + auto dir = params.dir; + std::vector, size_t>> input; + std::vector, size_t>> output; + std::vector> path_impls; + + GeneralPathColumnBuilder builder; + if (dir == Direction::kOut) { + foreach_vertex(input_vertex_list, [&](size_t index, label_t label, vid_t v) { + auto p = PathImpl::make_path_impl(label, v); + input.emplace_back(p, index); + }); + int depth = 0; + while (depth < params.hop_upper) { + output.clear(); + if (depth >= params.hop_lower) { + for (auto& [path, index] : input) { + builder.push_back_opt(Path::make_path(path)); + path_impls.emplace_back(path); + shuffle_offset.push_back(index); + } + } + if (depth + 1 >= params.hop_upper) { + break; + } + + for (auto& [path, index] : input) { + auto end = path->get_end(); + for (auto& label_triplet : labels) { + if (label_triplet.src_label == end.first) { + auto oe_iter = txn.GetOutEdgeIterator(end.first, label_triplet.dst_label, + label_triplet.edge_label, end.second); + while (oe_iter.IsValid()) { + std::shared_ptr new_path = + path->expand(label_triplet.dst_label, oe_iter.GetNeighbor()); + output.emplace_back(new_path, index); + oe_iter.Next(); + } + } + } + } + + input.clear(); + std::swap(input, output); + ++depth; + } + builder.set_path_impls(path_impls); + ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, params.keep_cols); + + return ctx; + } else if (dir == Direction::kBoth) { + foreach_vertex(input_vertex_list, [&](size_t index, label_t label, vid_t v) { + auto p = PathImpl::make_path_impl(label, v); + input.emplace_back(p, index); + }); + int depth = 0; + while (depth < params.hop_upper) { + output.clear(); + if (depth >= params.hop_lower) { + for (auto& [path, index] : input) { + builder.push_back_opt(Path::make_path(path)); + path_impls.emplace_back(path); + shuffle_offset.push_back(index); + } + } + if (depth + 1 >= params.hop_upper) { + break; + } + + for (auto& [path, index] : input) { + auto end = path->get_end(); + for (auto& label_triplet : labels) { + if (label_triplet.src_label == end.first) { + auto oe_iter = txn.GetOutEdgeIterator(end.first, label_triplet.dst_label, + label_triplet.edge_label, end.second); + while (oe_iter.IsValid()) { + auto new_path = path->expand(label_triplet.dst_label, oe_iter.GetNeighbor()); + output.emplace_back(new_path, index); + oe_iter.Next(); + } + } + if (label_triplet.dst_label == end.first) { + auto ie_iter = txn.GetInEdgeIterator(end.first, label_triplet.src_label, + label_triplet.edge_label, end.second); + while (ie_iter.IsValid()) { + auto new_path = path->expand(label_triplet.src_label, ie_iter.GetNeighbor()); + output.emplace_back(new_path, index); + ie_iter.Next(); + } + } + } + } + + input.clear(); + std::swap(input, output); + ++depth; + } + builder.set_path_impls(path_impls); + ctx.set_with_reshuffle_beta(params.alias, builder.finish(), shuffle_offset, params.keep_cols); + return ctx; + } else { + LOG(ERROR) << "Not implemented yet"; + RETURN_NOT_IMPLEMENTED_ERROR("Not implemented yet for direction in"); + } + return ctx; +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/project.h b/flex/engines/graph_db/runtime/common/operators/project.h index bc6fb0e5fcb3..d74396bc0336 100644 --- a/flex/engines/graph_db/runtime/common/operators/project.h +++ b/flex/engines/graph_db/runtime/common/operators/project.h @@ -102,8 +102,8 @@ class Project { return new_ctx; } - template - static Context map_value(const ReadTransaction& txn, Context&& ctx, + template + static Context map_value(const GraphInterface& txn, Context&& ctx, const std::tuple& exprs, bool is_append) { std::vector> new_columns; map_value_impl(ctx, exprs, ctx.row_num(), new_columns); @@ -134,9 +134,9 @@ class Project { return new_ctx; } - template + template static bl::result map_value_general( - const ReadTransaction& txn, Context&& ctx, + const GraphInterface& txn, Context&& ctx, const std::vector>& expressions, bool is_append) { if (!is_append) { std::vector> new_columns; diff --git a/flex/engines/graph_db/runtime/common/operators/scan.cc b/flex/engines/graph_db/runtime/common/operators/scan.cc deleted file mode 100644 index 9b260008cd71..000000000000 --- a/flex/engines/graph_db/runtime/common/operators/scan.cc +++ /dev/null @@ -1,63 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/operators/scan.h" - -#include "flex/engines/graph_db/runtime/common/leaf_utils.h" - -namespace gs { -namespace runtime { - -bl::result Scan::find_vertex_with_id(const ReadTransaction& txn, - label_t label, const Any& pk, - int alias, bool scan_oid) { - if (scan_oid) { - SLVertexColumnBuilder builder(label); - vid_t vid; - if (txn.GetVertexIndex(label, pk, vid)) { - builder.push_back_opt(vid); - } - Context ctx; - ctx.set(alias, builder.finish()); - return ctx; - } else { - SLVertexColumnBuilder builder(label); - vid_t vid{}; - int64_t gid{}; - if (pk.type == PropertyType::kInt64) { - gid = pk.AsInt64(); - } else if (pk.type == PropertyType::kInt32) { - gid = pk.AsInt32(); - } else { - LOG(ERROR) << "Unsupported primary key type " << pk.type; - RETURN_UNSUPPORTED_ERROR("Unsupported primary key type" + - pk.type.ToString()); - } - if (GlobalId::get_label_id(gid) == label) { - vid = GlobalId::get_vid(gid); - } else { - LOG(ERROR) << "Global id " << gid << " does not match label " << label; - return Context(); - } - builder.push_back_opt(vid); - Context ctx; - ctx.set(alias, builder.finish()); - return ctx; - } -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/scan.h b/flex/engines/graph_db/runtime/common/operators/scan.h index 0b73a4e70e0b..9ba6a3f55629 100644 --- a/flex/engines/graph_db/runtime/common/operators/scan.h +++ b/flex/engines/graph_db/runtime/common/operators/scan.h @@ -30,15 +30,15 @@ struct ScanParams { }; class Scan { public: - template - static bl::result scan_vertex(const ReadTransaction& txn, + template + static bl::result scan_vertex(const GraphInterface& txn, const ScanParams& params, const PRED_T& predicate) { Context ctx; if (params.tables.size() == 1) { label_t label = params.tables[0]; SLVertexColumnBuilder builder(label); - vid_t vnum = txn.GetVertexNum(label); + vid_t vnum = txn.VertexNum(label); for (vid_t vid = 0; vid != vnum; ++vid) { if (predicate(label, vid)) { builder.push_back_opt(vid); @@ -49,7 +49,7 @@ class Scan { MLVertexColumnBuilder builder; for (auto label : params.tables) { - vid_t vnum = txn.GetVertexNum(label); + vid_t vnum = txn.VertexNum(label); for (vid_t vid = 0; vid != vnum; ++vid) { if (predicate(label, vid)) { builder.push_back_vertex(std::make_pair(label, vid)); @@ -58,14 +58,14 @@ class Scan { } ctx.set(params.alias, builder.finish()); } else { - LOG(ERROR) << "No vertex labels in scan_vertex"; + LOG(ERROR) << "No vertex labels in scan_vertex: " << params.tables.size(); RETURN_BAD_REQUEST_ERROR("No valid vertex labels in scan_vertex"); } return ctx; } - template - static Context filter_gids(const ReadTransaction& txn, + template + static Context filter_gids(const GraphInterface& txn, const ScanParams& params, const PRED_T& predicate, const std::vector& gids) { Context ctx; @@ -95,8 +95,8 @@ class Scan { return ctx; } - template - static Context filter_oids(const ReadTransaction& txn, + template + static Context filter_oids(const GraphInterface& txn, const ScanParams& params, const PRED_T& predicate, const std::vector& oids) { Context ctx; @@ -131,9 +131,10 @@ class Scan { } // EXPR() is a function that returns the oid of the vertex - template - static Context find_vertex(const ReadTransaction& txn, label_t label, - const EXPR& expr, int alias, bool scan_oid) { + template + static Context find_vertex(const GraphInterface& txn, + label_t label, const EXPR& expr, int alias, + bool scan_oid) { Context ctx; SLVertexColumnBuilder builder(label); if (scan_oid) { @@ -155,11 +156,51 @@ class Scan { return ctx; } - static bl::result find_vertex_with_id(const ReadTransaction& txn, - label_t label, const Any& pk, - int alias, bool scan_oid); + template + static bl::result find_vertex_with_id( + const GraphInterface& txn, label_t label, const Any& pk, + int alias, bool scan_oid); }; +template +bl::result Scan::find_vertex_with_id( + const GraphInterface& txn, label_t label, const Any& pk, + int alias, bool scan_oid) { + if (scan_oid) { + SLVertexColumnBuilder builder(label); + vid_t vid; + if (txn.GetVertexIndex(label, pk, vid)) { + builder.push_back_opt(vid); + } + Context ctx; + ctx.set(alias, builder.finish()); + return ctx; + } else { + SLVertexColumnBuilder builder(label); + vid_t vid{}; + int64_t gid{}; + if (pk.type == PropertyType::kInt64) { + gid = pk.AsInt64(); + } else if (pk.type == PropertyType::kInt32) { + gid = pk.AsInt32(); + } else { + LOG(ERROR) << "Unsupported primary key type " << pk.type; + RETURN_UNSUPPORTED_ERROR("Unsupported primary key type" + + pk.type.ToString()); + } + if (GlobalId::get_label_id(gid) == label) { + vid = GlobalId::get_vid(gid); + } else { + LOG(ERROR) << "Global id " << gid << " does not match label " << label; + return Context(); + } + builder.push_back_opt(vid); + Context ctx; + ctx.set(alias, builder.finish()); + return ctx; + } +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/sink.cc b/flex/engines/graph_db/runtime/common/operators/sink.cc deleted file mode 100644 index 550e827a88d6..000000000000 --- a/flex/engines/graph_db/runtime/common/operators/sink.cc +++ /dev/null @@ -1,39 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/operators/sink.h" - -namespace gs { - -namespace runtime { -// TODO: Implement the sink function -void Sink::sink(const Context& ctx, Encoder& output) { - size_t row_num = ctx.row_num(); - size_t col_num = ctx.col_num(); - for (size_t i = 0; i < row_num; ++i) { - for (size_t j = 0; j < col_num; ++j) { - auto col = ctx.get(j); - if (col == nullptr) { - continue; - } - auto val = col->get_elem(row_num - i - 1); - // val.sink(output); - } - } -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/sink.h b/flex/engines/graph_db/runtime/common/operators/sink.h index 2e282c3876ea..6dcc94eac688 100644 --- a/flex/engines/graph_db/runtime/common/operators/sink.h +++ b/flex/engines/graph_db/runtime/common/operators/sink.h @@ -27,6 +27,21 @@ class Sink { static void sink(const Context& ctx, Encoder& output); }; +void Sink::sink(const Context& ctx, Encoder& output) { + size_t row_num = ctx.row_num(); + size_t col_num = ctx.col_num(); + for (size_t i = 0; i < row_num; ++i) { + for (size_t j = 0; j < col_num; ++j) { + auto col = ctx.get(j); + if (col == nullptr) { + continue; + } + auto val = col->get_elem(row_num - i - 1); + // val.sink(output); + } + } +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/union.cc b/flex/engines/graph_db/runtime/common/operators/union.cc deleted file mode 100644 index 72fefaed9f66..000000000000 --- a/flex/engines/graph_db/runtime/common/operators/union.cc +++ /dev/null @@ -1,38 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/operators/union.h" - -namespace gs { - -namespace runtime { - -Context Union::union_op(Context&& ctx1, Context&& ctx2) { - CHECK(ctx1.col_num() == ctx2.col_num()); - size_t col_num = ctx1.col_num(); - Context ret; - for (size_t col_i = 0; col_i < col_num; ++col_i) { - if (ctx1.get(col_i) == nullptr) { - CHECK(ctx2.get(col_i) == nullptr); - continue; - } - ret.set(col_i, ctx1.get(col_i)->union_col(ctx2.get(col_i))); - } - return ret; -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/operators/union.h b/flex/engines/graph_db/runtime/common/operators/union.h index 27d3789ea4b0..72158068314c 100644 --- a/flex/engines/graph_db/runtime/common/operators/union.h +++ b/flex/engines/graph_db/runtime/common/operators/union.h @@ -27,6 +27,20 @@ class Union { static Context union_op(Context&& ctx1, Context&& ctx2); }; +Context Union::union_op(Context&& ctx1, Context&& ctx2) { + CHECK(ctx1.col_num() == ctx2.col_num()); + size_t col_num = ctx1.col_num(); + Context ret; + for (size_t col_i = 0; col_i < col_num; ++col_i) { + if (ctx1.get(col_i) == nullptr) { + CHECK(ctx2.get(col_i) == nullptr); + continue; + } + ret.set(col_i, ctx1.get(col_i)->union_col(ctx2.get(col_i))); + } + return ret; +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/rt_any.cc b/flex/engines/graph_db/runtime/common/rt_any.cc deleted file mode 100644 index e3cf4a1d55d8..000000000000 --- a/flex/engines/graph_db/runtime/common/rt_any.cc +++ /dev/null @@ -1,804 +0,0 @@ -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/rt_any.h" - -namespace gs { - -namespace runtime { - -const RTAnyType RTAnyType::kVertex = - RTAnyType(RTAnyType::RTAnyTypeImpl::kVertex); -const RTAnyType RTAnyType::kEdge = RTAnyType(RTAnyType::RTAnyTypeImpl::kEdge); -const RTAnyType RTAnyType::kI64Value = - RTAnyType(RTAnyType::RTAnyTypeImpl::kI64Value); -const RTAnyType RTAnyType::kU64Value = - RTAnyType(RTAnyType::RTAnyTypeImpl::kU64Value); -const RTAnyType RTAnyType::kI32Value = - RTAnyType(RTAnyType::RTAnyTypeImpl::kI32Value); -const RTAnyType RTAnyType::kF64Value = - RTAnyType(RTAnyType::RTAnyTypeImpl::kF64Value); - -const RTAnyType RTAnyType::kBoolValue = - RTAnyType(RTAnyType::RTAnyTypeImpl::kBoolValue); -const RTAnyType RTAnyType::kStringValue = - RTAnyType(RTAnyType::RTAnyTypeImpl::kStringValue); -const RTAnyType RTAnyType::kVertexSetValue = - RTAnyType(RTAnyType::RTAnyTypeImpl::kVertexSetValue); -const RTAnyType RTAnyType::kStringSetValue = - RTAnyType(RTAnyType::RTAnyTypeImpl::kStringSetValue); -const RTAnyType RTAnyType::kUnknown = - RTAnyType(RTAnyType::RTAnyTypeImpl::kUnknown); -const RTAnyType RTAnyType::kDate32 = - RTAnyType(RTAnyType::RTAnyTypeImpl::kDate32); -const RTAnyType RTAnyType::kPath = RTAnyType(RTAnyType::RTAnyTypeImpl::kPath); -const RTAnyType RTAnyType::kNull = RTAnyType(RTAnyType::RTAnyTypeImpl::kNull); -const RTAnyType RTAnyType::kTuple = RTAnyType(RTAnyType::RTAnyTypeImpl::kTuple); -const RTAnyType RTAnyType::kList = RTAnyType(RTAnyType::RTAnyTypeImpl::kList); -const RTAnyType RTAnyType::kMap = RTAnyType(RTAnyType::RTAnyTypeImpl::kMap); -RTAny List::get(size_t idx) const { return impl_->get(idx); } -RTAnyType parse_from_ir_data_type(const ::common::IrDataType& dt) { - switch (dt.type_case()) { - case ::common::IrDataType::TypeCase::kDataType: { - const ::common::DataType ddt = dt.data_type(); - switch (ddt) { - case ::common::DataType::BOOLEAN: - return RTAnyType::kBoolValue; - case ::common::DataType::INT64: - return RTAnyType::kI64Value; - case ::common::DataType::STRING: - return RTAnyType::kStringValue; - case ::common::DataType::INT32: - return RTAnyType::kI32Value; - case ::common::DataType::DATE32: - return RTAnyType::kDate32; - case ::common::DataType::STRING_ARRAY: - return RTAnyType::kList; - case ::common::DataType::TIMESTAMP: - return RTAnyType::kDate32; - case ::common::DataType::DOUBLE: - return RTAnyType::kF64Value; - default: - LOG(FATAL) << "unrecoginized data type - " << ddt; - break; - } - } break; - case ::common::IrDataType::TypeCase::kGraphType: { - const ::common::GraphDataType gdt = dt.graph_type(); - switch (gdt.element_opt()) { - case ::common::GraphDataType_GraphElementOpt:: - GraphDataType_GraphElementOpt_VERTEX: - return RTAnyType::kVertex; - case ::common::GraphDataType_GraphElementOpt:: - GraphDataType_GraphElementOpt_EDGE: - return RTAnyType::kEdge; - default: - LOG(FATAL) << "unrecoginized graph data type"; - break; - } - } break; - default: - break; - } - - // LOG(FATAL) << "unknown"; - return RTAnyType::kUnknown; -} - -RTAny::RTAny() : type_(RTAnyType::kUnknown), value_() {} -RTAny::RTAny(RTAnyType type) : type_(type) {} - -RTAny::RTAny(const Any& val) { - if (val.type == PropertyType::Int64()) { - type_ = RTAnyType::kI64Value; - value_.i64_val = val.AsInt64(); - } else if (val.type == PropertyType::String()) { - type_ = RTAnyType::kStringValue; - value_.str_val = val.AsStringView(); - } else if (val.type == PropertyType::Date()) { - type_ = RTAnyType::kI64Value; - value_.i64_val = val.AsDate().milli_second; - } else if (val.type == PropertyType::Int32()) { - type_ = RTAnyType::kI32Value; - value_.i32_val = val.AsInt32(); - } else if (val.type == PropertyType::kDouble) { - type_ = RTAnyType::kF64Value; - value_.f64_val = val.AsDouble(); - } else if (val.type == PropertyType::Bool()) { - type_ = RTAnyType::kBoolValue; - value_.b_val = val.AsBool(); - } else { - LOG(FATAL) << "Any value: " << val.to_string() - << ", type = " << val.type.type_enum; - } -} - -RTAny::RTAny(const Path& p) { - type_ = RTAnyType::kPath; - value_.p = p; -} -RTAny::RTAny(const RTAny& rhs) : type_(rhs.type_) { - if (type_ == RTAnyType::kBoolValue) { - value_.b_val = rhs.value_.b_val; - } else if (type_ == RTAnyType::kI64Value) { - value_.i64_val = rhs.value_.i64_val; - } else if (type_ == RTAnyType::kI32Value) { - value_.i32_val = rhs.value_.i32_val; - } else if (type_ == RTAnyType::kVertex) { - value_.vertex = rhs.value_.vertex; - } else if (type_ == RTAnyType::kStringValue) { - value_.str_val = rhs.value_.str_val; - } else if (type_ == RTAnyType::kNull) { - // do nothing - } else if (type_ == RTAnyType::kTuple) { - value_.t = rhs.value_.t.dup(); - } else if (type_ == RTAnyType::kList) { - value_.list = rhs.value_.list; - } else if (type_ == RTAnyType::kF64Value) { - value_.f64_val = rhs.value_.f64_val; - } else if (type_ == RTAnyType::kMap) { - value_.map = rhs.value_.map; - } else { - LOG(FATAL) << "unexpected type: " << static_cast(type_.type_enum_); - } -} - -RTAny& RTAny::operator=(const RTAny& rhs) { - type_ = rhs.type_; - if (type_ == RTAnyType::kBoolValue) { - value_.b_val = rhs.value_.b_val; - } else if (type_ == RTAnyType::kI64Value) { - value_.i64_val = rhs.value_.i64_val; - } else if (type_ == RTAnyType::kI32Value) { - value_.i32_val = rhs.value_.i32_val; - } else if (type_ == RTAnyType::kVertex) { - value_.vertex = rhs.value_.vertex; - } else if (type_ == RTAnyType::kStringValue) { - value_.str_val = rhs.value_.str_val; - } else if (type_ == RTAnyType::kTuple) { - value_.t = rhs.value_.t.dup(); - } else if (type_ == RTAnyType::kList) { - value_.list = rhs.value_.list; - } else if (type_ == RTAnyType::kF64Value) { - value_.f64_val = rhs.value_.f64_val; - } else if (type_ == RTAnyType::kMap) { - value_.map = rhs.value_.map; - } else if (type_ == RTAnyType::kEdge) { - value_.edge = rhs.value_.edge; - } else { - LOG(FATAL) << "unexpected type: " << static_cast(type_.type_enum_); - } - return *this; -} - -RTAnyType RTAny::type() const { return type_; } - -RTAny RTAny::from_vertex(label_t l, vid_t v) { - RTAny ret; - ret.type_ = RTAnyType::kVertex; - ret.value_.vertex.first = l; - ret.value_.vertex.second = v; - return ret; -} - -RTAny RTAny::from_vertex(const std::pair& v) { - RTAny ret; - ret.type_ = RTAnyType::kVertex; - ret.value_.vertex = v; - return ret; -} - -RTAny RTAny::from_edge( - const std::tuple& v) { - RTAny ret; - ret.type_ = RTAnyType::kEdge; - ret.value_.edge = v; - return ret; -} - -RTAny RTAny::from_bool(bool v) { - RTAny ret; - ret.type_ = RTAnyType::kBoolValue; - ret.value_.b_val = v; - return ret; -} - -RTAny RTAny::from_int64(int64_t v) { - RTAny ret; - ret.type_ = RTAnyType::kI64Value; - ret.value_.i64_val = v; - return ret; -} - -RTAny RTAny::from_uint64(uint64_t v) { - RTAny ret; - ret.type_ = RTAnyType::kU64Value; - ret.value_.u64_val = v; - return ret; -} - -RTAny RTAny::from_int32(int v) { - RTAny ret; - ret.type_ = RTAnyType::kI32Value; - ret.value_.i32_val = v; - return ret; -} - -RTAny RTAny::from_string(const std::string& str) { - RTAny ret; - ret.type_ = RTAnyType::kStringValue; - ret.value_.str_val = std::string_view(str); - return ret; -} - -RTAny RTAny::from_string(const std::string_view& str) { - RTAny ret; - ret.type_ = RTAnyType::kStringValue; - ret.value_.str_val = str; - return ret; -} - -RTAny RTAny::from_string_set(const std::set& str_set) { - RTAny ret; - ret.type_ = RTAnyType::kStringSetValue; - ret.value_.str_set = &str_set; - return ret; -} - -RTAny RTAny::from_vertex_list(const std::vector& v_set) { - RTAny ret; - ret.type_ = RTAnyType::kVertexSetValue; - ret.value_.vset = &v_set; - return ret; -} - -RTAny RTAny::from_date32(Date v) { - RTAny ret; - ret.type_ = RTAnyType::kDate32; - ret.value_.i64_val = v.milli_second; - return ret; -} - -RTAny RTAny::from_tuple(std::vector&& v) { - RTAny ret; - ret.type_ = RTAnyType::kTuple; - ret.value_.t.init(std::move(v)); - return ret; -} - -RTAny RTAny::from_tuple(const Tuple& t) { - RTAny ret; - ret.type_ = RTAnyType::kTuple; - ret.value_.t = t.dup(); - return ret; -} - -RTAny RTAny::from_list(const List& l) { - RTAny ret; - ret.type_ = RTAnyType::kList; - ret.value_.list = std::move(l); - return ret; -} - -RTAny RTAny::from_double(double v) { - RTAny ret; - ret.type_ = RTAnyType::kF64Value; - ret.value_.f64_val = v; - return ret; -} - -RTAny RTAny::from_map(const Map& m) { - RTAny ret; - ret.type_ = RTAnyType::kMap; - ret.value_.map = std::move(m); - return ret; -} - -bool RTAny::as_bool() const { - if (type_ == RTAnyType::kNull) { - return false; - } - CHECK(type_ == RTAnyType::kBoolValue) - << "type_ = " << static_cast(type_.type_enum_); - return value_.b_val; -} -int RTAny::as_int32() const { - CHECK(type_ == RTAnyType::kI32Value) - << "type_ = " << static_cast(type_.type_enum_); - return value_.i32_val; -} -int64_t RTAny::as_int64() const { - CHECK(type_ == RTAnyType::kI64Value); - return value_.i64_val; -} -uint64_t RTAny::as_uint64() const { - CHECK(type_ == RTAnyType::kU64Value); - return value_.u64_val; -} -int64_t RTAny::as_date32() const { - CHECK(type_ == RTAnyType::kDate32); - return value_.i64_val; -} - -double RTAny::as_double() const { - CHECK(type_ == RTAnyType::kF64Value); - return value_.f64_val; -} - -const std::pair& RTAny::as_vertex() const { - CHECK(type_ == RTAnyType::kVertex); - return value_.vertex; -} -const std::tuple& RTAny::as_edge() - const { - CHECK(type_ == RTAnyType::kEdge); - return value_.edge; -} -const std::set& RTAny::as_string_set() const { - CHECK(type_ == RTAnyType::kStringSetValue); - return *value_.str_set; -} -std::string_view RTAny::as_string() const { - if (type_ == RTAnyType::kStringValue) { - return value_.str_val; - } else if (type_ == RTAnyType::kUnknown) { - return std::string_view(); - } else { - LOG(FATAL) << "unexpected type" << static_cast(type_.type_enum_); - return std::string_view(); - } -} - -List RTAny::as_list() const { - CHECK(type_ == RTAnyType::kList); - return value_.list; -} -const std::vector& RTAny::as_vertex_list() const { - CHECK(type_ == RTAnyType::kVertexSetValue); - return *value_.vset; -} - -Path RTAny::as_path() const { - CHECK(type_ == RTAnyType::kPath); - return value_.p; -} - -Tuple RTAny::as_tuple() const { - CHECK(type_ == RTAnyType::kTuple); - return value_.t; -} - -Map RTAny::as_map() const { - CHECK(type_ == RTAnyType::kMap); - return value_.map; -} - -int RTAny::numerical_cmp(const RTAny& other) const { - switch (type_.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - switch (other.type_.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI32Value: - return value_.i64_val - other.value_.i32_val; - case RTAnyType::RTAnyTypeImpl::kF64Value: - return value_.i64_val - other.value_.f64_val; - default: - LOG(FATAL) << "not support for " - << static_cast(other.type_.type_enum_); - } - break; - case RTAnyType::RTAnyTypeImpl::kI32Value: - switch (other.type_.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return value_.i32_val - other.value_.i64_val; - case RTAnyType::RTAnyTypeImpl::kF64Value: - return value_.i32_val - other.value_.f64_val; - default: - LOG(FATAL) << "not support for " - << static_cast(other.type_.type_enum_); - } - break; - case RTAnyType::RTAnyTypeImpl::kF64Value: - switch (other.type_.type_enum_) { - case RTAnyType::RTAnyTypeImpl::kI64Value: - return value_.f64_val - other.value_.i64_val; - case RTAnyType::RTAnyTypeImpl::kI32Value: - return value_.f64_val - other.value_.i32_val; - default: - LOG(FATAL) << "not support for " << static_cast(type_.type_enum_); - } - break; - default: - LOG(FATAL) << "not support for " << static_cast(type_.type_enum_); - } -} -inline static bool is_numerical_type(const RTAnyType& type) { - return type == RTAnyType::kI64Value || type == RTAnyType::kI32Value || - type == RTAnyType::kF64Value; -} - -bool RTAny::operator<(const RTAny& other) const { - if (type_.type_enum_ != other.type_.type_enum_) { - if (is_numerical_type(type_) && is_numerical_type(other.type_)) { - return numerical_cmp(other) < 0; - } else { - return false; - } - } - if (type_ == RTAnyType::kI64Value) { - return value_.i64_val < other.value_.i64_val; - - } else if (type_ == RTAnyType::kI32Value) { - return value_.i32_val < other.value_.i32_val; - - } else if (type_ == RTAnyType::kStringValue) { - return value_.str_val < other.value_.str_val; - } else if (type_ == RTAnyType::kDate32) { - return value_.i64_val < other.value_.i64_val; - } else if (type_ == RTAnyType::kF64Value) { - return value_.f64_val < other.value_.f64_val; - } - - LOG(FATAL) << "not support for " << static_cast(type_.type_enum_); - return true; -} - -bool RTAny::operator==(const RTAny& other) const { - // assert(type_ == other.type_); - if (type_.type_enum_ != other.type_.type_enum_) { - if (is_numerical_type(type_) && is_numerical_type(other.type_)) { - return numerical_cmp(other) == 0; - } else { - return false; - } - } - - if (type_ == RTAnyType::kI64Value) { - return value_.i64_val == other.value_.i64_val; - } else if (type_ == RTAnyType::kI32Value) { - return value_.i32_val == other.value_.i32_val; - } else if (type_ == RTAnyType::kStringValue) { - return value_.str_val == other.value_.str_val; - } else if (type_ == RTAnyType::kVertex) { - return value_.vertex == other.value_.vertex; - } else if (type_ == RTAnyType::kDate32) { - return value_.i64_val == other.value_.i64_val; - } - - if (type_ == RTAnyType::kI64Value && other.type_ == RTAnyType::kI32Value) { - return value_.i64_val == other.value_.i32_val; - } else if (type_ == RTAnyType::kI32Value && - other.type_ == RTAnyType::kI64Value) { - return value_.i32_val == other.value_.i64_val; - } else if (type_ == RTAnyType::kF64Value) { - return value_.f64_val == other.value_.f64_val; - } - - LOG(FATAL) << "not support..." << static_cast(type_.type_enum_); - return true; -} - -RTAny RTAny::operator+(const RTAny& other) const { - if (type_ == RTAnyType::kI64Value && other.type_ == RTAnyType::kI32Value) { - return RTAny::from_int64(value_.i64_val + other.value_.i32_val); - } else if (type_ == RTAnyType::kI32Value && - other.type_ == RTAnyType::kI64Value) { - return RTAny::from_int64(value_.i32_val * 1l + other.value_.i64_val); - } - if (type_ == RTAnyType::kF64Value) { - return RTAny::from_double(value_.f64_val + other.value_.f64_val); - } else if (type_ == RTAnyType::kI64Value) { - return RTAny::from_int64(value_.i64_val + other.value_.i64_val); - } else if (type_ == RTAnyType::kI32Value) { - return RTAny::from_int32(value_.i32_val + other.value_.i32_val); - } - - LOG(FATAL) << "not support" << static_cast(type_.type_enum_); - return RTAny(); -} - -RTAny RTAny::operator-(const RTAny& other) const { - // CHECK(type_ == other.type_); - - if (type_ == RTAnyType::kI64Value && other.type_ == RTAnyType::kI32Value) { - return RTAny::from_int64(value_.i64_val - other.value_.i32_val); - } else if (type_ == RTAnyType::kI32Value && - other.type_ == RTAnyType::kI64Value) { - return RTAny::from_int64(value_.i32_val * 1l - other.value_.i64_val); - } - if (type_ == RTAnyType::kF64Value) { - return RTAny::from_double(value_.f64_val - other.value_.f64_val); - } else if (type_ == RTAnyType::kI64Value) { - return RTAny::from_int64(value_.i64_val - other.value_.i64_val); - } else if (type_ == RTAnyType::kI32Value) { - return RTAny::from_int32(value_.i32_val - other.value_.i32_val); - } - LOG(FATAL) << "not support"; - return RTAny(); -} - -RTAny RTAny::operator/(const RTAny& other) const { - // CHECK(type_ == other.type_); - - if (type_ == RTAnyType::kI64Value && other.type_ == RTAnyType::kI32Value) { - return RTAny::from_int64(value_.i64_val / other.value_.i32_val); - } else if (type_ == RTAnyType::kI32Value && - other.type_ == RTAnyType::kI64Value) { - return RTAny::from_int64(value_.i32_val * 1l / other.value_.i64_val); - } - - if (type_ == RTAnyType::kI64Value) { - return RTAny::from_int64(value_.i64_val / other.value_.i64_val); - } else if (type_ == RTAnyType::kF64Value) { - return RTAny::from_double(value_.f64_val / other.value_.f64_val); - } else if (type_ == RTAnyType::kI32Value) { - return RTAny::from_int32(value_.i32_val / other.value_.i32_val); - } - LOG(FATAL) << "not support"; - return RTAny(); -} - -void RTAny::sink_impl(common::Value* value) const { - if (type_ == RTAnyType::kI64Value) { - value->set_i64(value_.i64_val); - } else if (type_ == RTAnyType::kStringValue) { - value->set_str(value_.str_val.data(), value_.str_val.size()); - } else if (type_ == RTAnyType::kI32Value) { - value->set_i32(value_.i32_val); - } else if (type_ == RTAnyType::kStringSetValue) { - LOG(FATAL) << "not support string set sink"; - } else if (type_ == RTAnyType::kDate32) { - value->set_i64(value_.i64_val); - } else if (type_ == RTAnyType::kBoolValue) { - value->set_boolean(value_.b_val); - } else if (type_ == RTAnyType::kF64Value) { - value->set_f64(value_.f64_val); - } else if (type_ == RTAnyType::kList) { - LOG(FATAL) << "not support list sink"; - } else if (type_ == RTAnyType::kTuple) { - auto tup = value_.t; - for (size_t i = 0; i < value_.t.size(); ++i) { - std::string s = tup.get(i).to_string(); - value->mutable_str_array()->add_item(s.data(), s.size()); - } - } else { - LOG(FATAL) << "not implemented for " << static_cast(type_.type_enum_); - } -} - -static void sink_any(const Any& any, common::Value* value) { - if (any.type == PropertyType::Int64()) { - value->set_i64(any.AsInt64()); - } else if (any.type == PropertyType::StringView()) { - auto str = any.AsStringView(); - value->set_str(str.data(), str.size()); - } else if (any.type == PropertyType::Date()) { - value->set_i64(any.AsDate().milli_second); - } else if (any.type == PropertyType::Int32()) { - value->set_i32(any.AsInt32()); - } else if (any.type == PropertyType::Double()) { - value->set_f64(any.AsDouble()); - } else if (any.type == PropertyType::Bool()) { - value->set_boolean(any.AsBool()); - } else if (any.type == PropertyType::Double()) { - value->set_f64(any.AsDouble()); - } else { - LOG(FATAL) << "Any value: " << any.to_string() - << ", type = " << any.type.type_enum; - } -} - -void sink_vertex(const gs::ReadTransaction& txn, - const std::pair& vertex, results::Vertex* v) { - v->mutable_label()->set_id(vertex.first); - v->set_id(encode_unique_vertex_id(vertex.first, vertex.second)); - // TODO: add properties - const auto& names = - txn.graph().schema().get_vertex_property_names(vertex.first); - for (size_t i = 0; i < names.size(); ++i) { - auto prop = v->add_properties(); - prop->mutable_key()->set_name(names[i]); - sink_any(txn.graph().get_vertex_table(vertex.first).at(vertex.second, i), - prop->mutable_value()); - } -} - -void RTAny::sink(const gs::ReadTransaction& txn, int id, - results::Column* col) const { - col->mutable_name_or_id()->set_id(id); - if (type_ == RTAnyType::kList) { - auto collection = col->mutable_entry()->mutable_collection(); - for (size_t i = 0; i < value_.list.size(); ++i) { - value_.list.get(i).sink_impl( - collection->add_collection()->mutable_object()); - } - } else if (type_ == RTAnyType::kStringSetValue) { - auto collection = col->mutable_entry()->mutable_collection(); - for (auto& s : *value_.str_set) { - collection->add_collection()->mutable_object()->set_str(s); - } - } else if (type_ == RTAnyType::kTuple) { - auto collection = col->mutable_entry()->mutable_collection(); - for (size_t i = 0; i < value_.t.size(); ++i) { - value_.t.get(i).sink_impl(collection->add_collection()->mutable_object()); - } - } else if (type_ == RTAnyType::kVertex) { - auto v = col->mutable_entry()->mutable_element()->mutable_vertex(); - sink_vertex(txn, value_.vertex, v); - - } else if (type_ == RTAnyType::kMap) { - auto mp = col->mutable_entry()->mutable_map(); - auto [keys_ptr, vals_ptr] = value_.map.key_vals(); - auto& keys = *keys_ptr; - auto& vals = *vals_ptr; - for (size_t i = 0; i < keys.size(); ++i) { - if (vals[i].is_null()) { - continue; - } - auto ret = mp->add_key_values(); - ret->mutable_key()->set_str(keys[i]); - if (vals[i].type_ == RTAnyType::kVertex) { - auto v = ret->mutable_value()->mutable_element()->mutable_vertex(); - sink_vertex(txn, vals[i].as_vertex(), v); - } else { - vals[i].sink_impl( - ret->mutable_value()->mutable_element()->mutable_object()); - } - } - - } else if (type_ == RTAnyType::kEdge) { - auto e = col->mutable_entry()->mutable_element()->mutable_edge(); - auto [label, src, dst, prop, dir] = this->as_edge(); - e->mutable_src_label()->set_id(label.src_label); - e->mutable_dst_label()->set_id(label.dst_label); - auto edge_label = generate_edge_label_id(label.src_label, label.dst_label, - label.edge_label); - e->mutable_label()->set_id(label.edge_label); - e->set_src_id(encode_unique_vertex_id(label.src_label, src)); - e->set_dst_id(encode_unique_vertex_id(label.dst_label, dst)); - e->set_id(encode_unique_edge_id(edge_label, src, dst)); - auto& prop_names = txn.schema().get_edge_property_names( - label.src_label, label.dst_label, label.edge_label); - if (prop_names.size() == 1) { - auto props = e->add_properties(); - props->mutable_key()->set_name(prop_names[0]); - sink_any(prop, e->mutable_properties(0)->mutable_value()); - } else if (prop_names.size() > 1) { - auto rv = prop.AsRecordView(); - if (rv.size() != prop_names.size()) { - LOG(ERROR) << "record view size not match with prop names"; - } - for (size_t i = 0; i < prop_names.size(); ++i) { - auto props = e->add_properties(); - props->mutable_key()->set_name(prop_names[i]); - sink_any(rv[i], props->mutable_value()); - } - } - } else if (type_ == RTAnyType::kPath) { - LOG(FATAL) << "not support path sink"; - - } else { - sink_impl(col->mutable_entry()->mutable_element()->mutable_object()); - } -} - -void RTAny::encode_sig(RTAnyType type, Encoder& encoder) const { - if (type == RTAnyType::kI64Value) { - encoder.put_long(this->as_int64()); - } else if (type == RTAnyType::kStringValue) { - encoder.put_string_view(this->as_string()); - } else if (type == RTAnyType::kI32Value) { - encoder.put_int(this->as_int32()); - } else if (type == RTAnyType::kVertex) { - const auto& v = this->value_.vertex; - encoder.put_byte(v.first); - encoder.put_int(v.second); - } else if (type == RTAnyType::kEdge) { - const auto& [label, src, dst, prop, dir] = this->as_edge(); - - encoder.put_byte(label.src_label); - encoder.put_byte(label.dst_label); - encoder.put_byte(label.edge_label); - encoder.put_int(src); - encoder.put_int(dst); - encoder.put_byte(dir == Direction::kOut ? 1 : 0); - - } else if (type == RTAnyType::kBoolValue) { - encoder.put_byte(this->as_bool() ? 1 : 0); - } else if (type == RTAnyType::kList) { - encoder.put_int(this->as_list().size()); - List list = this->as_list(); - for (size_t i = 0; i < list.size(); ++i) { - list.get(i).encode_sig(list.get(i).type(), encoder); - } - } else if (type == RTAnyType::kTuple) { - Tuple tuple = this->as_tuple(); - encoder.put_int(tuple.size()); - for (size_t i = 0; i < tuple.size(); ++i) { - tuple.get(i).encode_sig(tuple.get(i).type(), encoder); - } - } else if (type == RTAnyType::kNull) { - encoder.put_int(-1); - } else if (type == RTAnyType::kF64Value) { - encoder.put_double(this->as_double()); - } else { - LOG(FATAL) << "not implemented for " << static_cast(type_.type_enum_); - } -} - -std::string RTAny::to_string() const { - if (type_ == RTAnyType::kI64Value) { - return std::to_string(value_.i64_val); - } else if (type_ == RTAnyType::kStringValue) { - return std::string(value_.str_val); - } else if (type_ == RTAnyType::kI32Value) { - return std::to_string(value_.i32_val); - } else if (type_ == RTAnyType::kVertex) { -#if 0 - return std::string("v") + - std::to_string(static_cast(value_.vertex.first)) + "-" + - std::to_string(value_.vertex.second); -#else - return std::to_string(value_.vertex.second); -#endif - } else if (type_ == RTAnyType::kStringSetValue) { - std::string ret = "{"; - for (auto& str : *value_.str_set) { - ret += str; - ret += ", "; - } - ret += "}"; - return ret; - } else if (type_ == RTAnyType::kEdge) { - auto [label, src, dst, prop, dir] = value_.edge; - return std::to_string(src) + " -> " + std::to_string(dst); - } else if (type_ == RTAnyType::kPath) { - return value_.p.to_string(); - } else if (type_ == RTAnyType::kBoolValue) { - return value_.b_val ? "true" : "false"; - } else if (type_ == RTAnyType::kDate32) { - return std::to_string(value_.i64_val); - } else if (type_ == RTAnyType::kList) { - std::string ret = "["; - for (size_t i = 0; i < value_.list.size(); ++i) { - ret += value_.list.get(i).to_string(); - if (i != value_.list.size() - 1) { - ret += ", "; - } - } - ret += "]"; - return ret; - } else if (type_ == RTAnyType::kTuple) { - std::string ret = "("; - for (size_t i = 0; i < value_.t.size(); ++i) { - ret += value_.t.get(i).to_string(); - if (i != value_.t.size() - 1) { - ret += ", "; - } - } - ret += ")"; - return ret; - } else if (type_ == RTAnyType::kNull) { - return "null"; - } else if (type_ == RTAnyType::kF64Value) { - return std::to_string(value_.f64_val); - } else { - LOG(FATAL) << "not implemented for " << static_cast(type_.type_enum_); - return ""; - } -} - -} // namespace runtime - -} // namespace gs diff --git a/flex/engines/graph_db/runtime/common/rt_any.h b/flex/engines/graph_db/runtime/common/rt_any.h index cc5371e4005f..e2f49e4a5d74 100644 --- a/flex/engines/graph_db/runtime/common/rt_any.h +++ b/flex/engines/graph_db/runtime/common/rt_any.h @@ -19,7 +19,6 @@ #include "flex/proto_generated_gie/results.pb.h" #include "flex/proto_generated_gie/type.pb.h" -#include "flex/engines/graph_db/database/read_transaction.h" #include "flex/engines/graph_db/runtime/common/types.h" #include "flex/utils/app_utils.h" @@ -27,6 +26,9 @@ namespace gs { namespace runtime { +template +class GraphInterface; + class PathImpl { public: static std::shared_ptr make_path_impl(label_t label, vid_t v) { @@ -112,9 +114,7 @@ class Tuple { // delete props_; } } - void init(std::vector&& vals) { - props_ = new std::vector(vals); - } + void init(std::vector&& vals) { props_ = new std::vector(vals); } // not support for path Tuple dup() const { Tuple new_tuple; @@ -186,14 +186,10 @@ class RTAnyType { static const RTAnyType kMap; RTAnyType() : type_enum_(RTAnyTypeImpl::kUnknown) {} - RTAnyType(const RTAnyType& other) - : type_enum_(other.type_enum_), null_able_(other.null_able_) {} + RTAnyType(const RTAnyType& other) : type_enum_(other.type_enum_), null_able_(other.null_able_) {} RTAnyType(RTAnyTypeImpl type) : type_enum_(type), null_able_(false) {} - RTAnyType(RTAnyTypeImpl type, bool null_able) - : type_enum_(type), null_able_(null_able) {} - bool operator==(const RTAnyType& other) const { - return type_enum_ == other.type_enum_; - } + RTAnyType(RTAnyTypeImpl type, bool null_able) : type_enum_(type), null_able_(null_able) {} + bool operator==(const RTAnyType& other) const { return type_enum_ == other.type_enum_; } RTAnyTypeImpl type_enum_; bool null_able_; }; @@ -205,8 +201,7 @@ class Map { m.map_ = impl; return m; } - std::pair*, const std::vector*> - key_vals() const { + std::pair*, const std::vector*> key_vals() const { return std::make_pair(map_.keys, map_.values); } @@ -251,8 +246,7 @@ class RTAny { static RTAny from_vertex(label_t l, vid_t v); static RTAny from_vertex(const std::pair& v); - static RTAny from_edge( - const std::tuple& v); + static RTAny from_edge(const std::tuple& v); static RTAny from_bool(bool v); static RTAny from_int64(int64_t v); static RTAny from_uint64(uint64_t v); @@ -292,8 +286,6 @@ class RTAny { RTAny operator-(const RTAny& other) const; RTAny operator/(const RTAny& other) const; - void sink(const gs::ReadTransaction& txn, int id, - results::Column* column) const; void encode_sig(RTAnyType type, Encoder& encoder) const; std::string to_string() const; @@ -301,9 +293,14 @@ class RTAny { RTAnyType type() const; private: - void sink_impl(common::Value* collection) const; RTAnyType type_; RTAnyValue value_; + + template + friend void sink(const RTAny& any, const GraphInterface& txn, int id, + results::Column* col); + + friend void sink_impl(const RTAny& any, common::Value* value); }; template @@ -327,24 +324,16 @@ struct TypedConverter { template <> struct TypedConverter> { static RTAnyType type() { return RTAnyType::kStringSetValue; } - static const std::set to_typed(const RTAny& val) { - return val.as_string_set(); - } - static RTAny from_typed(const std::set& val) { - return RTAny::from_string_set(val); - } + static const std::set to_typed(const RTAny& val) { return val.as_string_set(); } + static RTAny from_typed(const std::set& val) { return RTAny::from_string_set(val); } static const std::string name() { return "set"; } }; template <> struct TypedConverter> { static RTAnyType type() { return RTAnyType::kVertexSetValue; } - static const std::vector& to_typed(const RTAny& val) { - return val.as_vertex_list(); - } - static RTAny from_typed(const std::vector& val) { - return RTAny::from_vertex_list(val); - } + static const std::vector& to_typed(const RTAny& val) { return val.as_vertex_list(); } + static RTAny from_typed(const std::vector& val) { return RTAny::from_vertex_list(val); } static const std::string name() { return "vector"; } }; @@ -352,9 +341,7 @@ template <> struct TypedConverter { static RTAnyType type() { return RTAnyType::kStringValue; } static std::string_view to_typed(const RTAny& val) { return val.as_string(); } - static RTAny from_typed(const std::string_view& val) { - return RTAny::from_string(val); - } + static RTAny from_typed(const std::string_view& val) { return RTAny::from_string(val); } static const std::string name() { return "string_view"; } static std::string_view typed_from_string(const std::string& str) { return std::string_view(str.data(), str.size()); @@ -400,9 +387,7 @@ template <> struct TypedConverter { static RTAnyType type() { return RTAnyType::kTuple; } static Tuple to_typed(const RTAny& val) { return val.as_tuple(); } - static RTAny from_typed(Tuple val) { - return RTAny::from_tuple(std::move(val)); - } + static RTAny from_typed(Tuple val) { return RTAny::from_tuple(std::move(val)); } static const std::string name() { return "tuple"; } }; @@ -423,8 +408,7 @@ class ListImpl : ListImplBase { return std::shared_ptr(static_cast(new_list)); } - static std::shared_ptr make_list_impl( - const std::vector& vals) { + static std::shared_ptr make_list_impl(const std::vector& vals) { auto new_list = new ListImpl(); for (auto& val : vals) { if (val.is_null()) { @@ -460,24 +444,21 @@ template <> class ListImpl : public ListImplBase { public: ListImpl() = default; - static std::shared_ptr make_list_impl( - std::vector&& vals) { + static std::shared_ptr make_list_impl(std::vector&& vals) { auto new_list = new ListImpl(); new_list->list_ = std::move(vals); new_list->is_valid_.resize(new_list->list_.size(), true); return std::shared_ptr(static_cast(new_list)); } - static std::shared_ptr make_list_impl( - const std::vector& vals) { + static std::shared_ptr make_list_impl(const std::vector& vals) { auto new_list = new ListImpl(); for (auto& val : vals) { if (val.is_null()) { new_list->is_valid_.push_back(false); new_list->list_.push_back(""); } else { - new_list->list_.push_back( - std::string(TypedConverter::to_typed(val))); + new_list->list_.push_back(std::string(TypedConverter::to_typed(val))); new_list->is_valid_.push_back(true); } } @@ -503,6 +484,621 @@ class ListImpl : public ListImplBase { std::vector list_; std::vector is_valid_; }; + +const RTAnyType RTAnyType::kVertex = RTAnyType(RTAnyType::RTAnyTypeImpl::kVertex); +const RTAnyType RTAnyType::kEdge = RTAnyType(RTAnyType::RTAnyTypeImpl::kEdge); +const RTAnyType RTAnyType::kI64Value = RTAnyType(RTAnyType::RTAnyTypeImpl::kI64Value); +const RTAnyType RTAnyType::kU64Value = RTAnyType(RTAnyType::RTAnyTypeImpl::kU64Value); +const RTAnyType RTAnyType::kI32Value = RTAnyType(RTAnyType::RTAnyTypeImpl::kI32Value); +const RTAnyType RTAnyType::kF64Value = RTAnyType(RTAnyType::RTAnyTypeImpl::kF64Value); + +const RTAnyType RTAnyType::kBoolValue = RTAnyType(RTAnyType::RTAnyTypeImpl::kBoolValue); +const RTAnyType RTAnyType::kStringValue = RTAnyType(RTAnyType::RTAnyTypeImpl::kStringValue); +const RTAnyType RTAnyType::kVertexSetValue = RTAnyType(RTAnyType::RTAnyTypeImpl::kVertexSetValue); +const RTAnyType RTAnyType::kStringSetValue = RTAnyType(RTAnyType::RTAnyTypeImpl::kStringSetValue); +const RTAnyType RTAnyType::kUnknown = RTAnyType(RTAnyType::RTAnyTypeImpl::kUnknown); +const RTAnyType RTAnyType::kDate32 = RTAnyType(RTAnyType::RTAnyTypeImpl::kDate32); +const RTAnyType RTAnyType::kPath = RTAnyType(RTAnyType::RTAnyTypeImpl::kPath); +const RTAnyType RTAnyType::kNull = RTAnyType(RTAnyType::RTAnyTypeImpl::kNull); +const RTAnyType RTAnyType::kTuple = RTAnyType(RTAnyType::RTAnyTypeImpl::kTuple); +const RTAnyType RTAnyType::kList = RTAnyType(RTAnyType::RTAnyTypeImpl::kList); +const RTAnyType RTAnyType::kMap = RTAnyType(RTAnyType::RTAnyTypeImpl::kMap); +RTAny List::get(size_t idx) const { return impl_->get(idx); } +RTAnyType parse_from_ir_data_type(const ::common::IrDataType& dt) { + switch (dt.type_case()) { + case ::common::IrDataType::TypeCase::kDataType: { + const ::common::DataType ddt = dt.data_type(); + switch (ddt) { + case ::common::DataType::BOOLEAN: + return RTAnyType::kBoolValue; + case ::common::DataType::INT64: + return RTAnyType::kI64Value; + case ::common::DataType::STRING: + return RTAnyType::kStringValue; + case ::common::DataType::INT32: + return RTAnyType::kI32Value; + case ::common::DataType::DATE32: + return RTAnyType::kDate32; + case ::common::DataType::STRING_ARRAY: + return RTAnyType::kList; + case ::common::DataType::TIMESTAMP: + return RTAnyType::kDate32; + case ::common::DataType::DOUBLE: + return RTAnyType::kF64Value; + default: + LOG(FATAL) << "unrecoginized data type - " << ddt; + break; + } + } break; + case ::common::IrDataType::TypeCase::kGraphType: { + const ::common::GraphDataType gdt = dt.graph_type(); + switch (gdt.element_opt()) { + case ::common::GraphDataType_GraphElementOpt::GraphDataType_GraphElementOpt_VERTEX: + return RTAnyType::kVertex; + case ::common::GraphDataType_GraphElementOpt::GraphDataType_GraphElementOpt_EDGE: + return RTAnyType::kEdge; + default: + LOG(FATAL) << "unrecoginized graph data type"; + break; + } + } break; + default: + break; + } + + // LOG(FATAL) << "unknown"; + return RTAnyType::kUnknown; +} + +RTAny::RTAny() : type_(RTAnyType::kUnknown), value_() {} +RTAny::RTAny(RTAnyType type) : type_(type) {} + +RTAny::RTAny(const Any& val) { + if (val.type == PropertyType::Int64()) { + type_ = RTAnyType::kI64Value; + value_.i64_val = val.AsInt64(); + } else if (val.type == PropertyType::String()) { + type_ = RTAnyType::kStringValue; + value_.str_val = val.AsStringView(); + } else if (val.type == PropertyType::Date()) { + type_ = RTAnyType::kI64Value; + value_.i64_val = val.AsDate().milli_second; + } else if (val.type == PropertyType::Int32()) { + type_ = RTAnyType::kI32Value; + value_.i32_val = val.AsInt32(); + } else if (val.type == PropertyType::kDouble) { + type_ = RTAnyType::kF64Value; + value_.f64_val = val.AsDouble(); + } else if (val.type == PropertyType::Bool()) { + type_ = RTAnyType::kBoolValue; + value_.b_val = val.AsBool(); + } else { + LOG(FATAL) << "Any value: " << val.to_string() << ", type = " << val.type.type_enum; + } +} + +RTAny::RTAny(const Path& p) { + type_ = RTAnyType::kPath; + value_.p = p; +} +RTAny::RTAny(const RTAny& rhs) : type_(rhs.type_) { + if (type_ == RTAnyType::kBoolValue) { + value_.b_val = rhs.value_.b_val; + } else if (type_ == RTAnyType::kI64Value) { + value_.i64_val = rhs.value_.i64_val; + } else if (type_ == RTAnyType::kI32Value) { + value_.i32_val = rhs.value_.i32_val; + } else if (type_ == RTAnyType::kVertex) { + value_.vertex = rhs.value_.vertex; + } else if (type_ == RTAnyType::kStringValue) { + value_.str_val = rhs.value_.str_val; + } else if (type_ == RTAnyType::kNull) { + // do nothing + } else if (type_ == RTAnyType::kTuple) { + value_.t = rhs.value_.t.dup(); + } else if (type_ == RTAnyType::kList) { + value_.list = rhs.value_.list; + } else if (type_ == RTAnyType::kF64Value) { + value_.f64_val = rhs.value_.f64_val; + } else if (type_ == RTAnyType::kMap) { + value_.map = rhs.value_.map; + } else { + LOG(FATAL) << "unexpected type: " << static_cast(type_.type_enum_); + } +} + +RTAny& RTAny::operator=(const RTAny& rhs) { + type_ = rhs.type_; + if (type_ == RTAnyType::kBoolValue) { + value_.b_val = rhs.value_.b_val; + } else if (type_ == RTAnyType::kI64Value) { + value_.i64_val = rhs.value_.i64_val; + } else if (type_ == RTAnyType::kI32Value) { + value_.i32_val = rhs.value_.i32_val; + } else if (type_ == RTAnyType::kVertex) { + value_.vertex = rhs.value_.vertex; + } else if (type_ == RTAnyType::kStringValue) { + value_.str_val = rhs.value_.str_val; + } else if (type_ == RTAnyType::kTuple) { + value_.t = rhs.value_.t.dup(); + } else if (type_ == RTAnyType::kList) { + value_.list = rhs.value_.list; + } else if (type_ == RTAnyType::kF64Value) { + value_.f64_val = rhs.value_.f64_val; + } else if (type_ == RTAnyType::kMap) { + value_.map = rhs.value_.map; + } else if (type_ == RTAnyType::kEdge) { + value_.edge = rhs.value_.edge; + } else { + LOG(FATAL) << "unexpected type: " << static_cast(type_.type_enum_); + } + return *this; +} + +RTAnyType RTAny::type() const { return type_; } + +RTAny RTAny::from_vertex(label_t l, vid_t v) { + RTAny ret; + ret.type_ = RTAnyType::kVertex; + ret.value_.vertex.first = l; + ret.value_.vertex.second = v; + return ret; +} + +RTAny RTAny::from_vertex(const std::pair& v) { + RTAny ret; + ret.type_ = RTAnyType::kVertex; + ret.value_.vertex = v; + return ret; +} + +RTAny RTAny::from_edge(const std::tuple& v) { + RTAny ret; + ret.type_ = RTAnyType::kEdge; + ret.value_.edge = v; + return ret; +} + +RTAny RTAny::from_bool(bool v) { + RTAny ret; + ret.type_ = RTAnyType::kBoolValue; + ret.value_.b_val = v; + return ret; +} + +RTAny RTAny::from_int64(int64_t v) { + RTAny ret; + ret.type_ = RTAnyType::kI64Value; + ret.value_.i64_val = v; + return ret; +} + +RTAny RTAny::from_uint64(uint64_t v) { + RTAny ret; + ret.type_ = RTAnyType::kU64Value; + ret.value_.u64_val = v; + return ret; +} + +RTAny RTAny::from_int32(int v) { + RTAny ret; + ret.type_ = RTAnyType::kI32Value; + ret.value_.i32_val = v; + return ret; +} + +RTAny RTAny::from_string(const std::string& str) { + RTAny ret; + ret.type_ = RTAnyType::kStringValue; + ret.value_.str_val = std::string_view(str); + return ret; +} + +RTAny RTAny::from_string(const std::string_view& str) { + RTAny ret; + ret.type_ = RTAnyType::kStringValue; + ret.value_.str_val = str; + return ret; +} + +RTAny RTAny::from_string_set(const std::set& str_set) { + RTAny ret; + ret.type_ = RTAnyType::kStringSetValue; + ret.value_.str_set = &str_set; + return ret; +} + +RTAny RTAny::from_vertex_list(const std::vector& v_set) { + RTAny ret; + ret.type_ = RTAnyType::kVertexSetValue; + ret.value_.vset = &v_set; + return ret; +} + +RTAny RTAny::from_date32(Date v) { + RTAny ret; + ret.type_ = RTAnyType::kDate32; + ret.value_.i64_val = v.milli_second; + return ret; +} + +RTAny RTAny::from_tuple(std::vector&& v) { + RTAny ret; + ret.type_ = RTAnyType::kTuple; + ret.value_.t.init(std::move(v)); + return ret; +} + +RTAny RTAny::from_tuple(const Tuple& t) { + RTAny ret; + ret.type_ = RTAnyType::kTuple; + ret.value_.t = t.dup(); + return ret; +} + +RTAny RTAny::from_list(const List& l) { + RTAny ret; + ret.type_ = RTAnyType::kList; + ret.value_.list = std::move(l); + return ret; +} + +RTAny RTAny::from_double(double v) { + RTAny ret; + ret.type_ = RTAnyType::kF64Value; + ret.value_.f64_val = v; + return ret; +} + +RTAny RTAny::from_map(const Map& m) { + RTAny ret; + ret.type_ = RTAnyType::kMap; + ret.value_.map = std::move(m); + return ret; +} + +bool RTAny::as_bool() const { + if (type_ == RTAnyType::kNull) { + return false; + } + CHECK(type_ == RTAnyType::kBoolValue) << "type_ = " << static_cast(type_.type_enum_); + return value_.b_val; +} +int RTAny::as_int32() const { + CHECK(type_ == RTAnyType::kI32Value) << "type_ = " << static_cast(type_.type_enum_); + return value_.i32_val; +} +int64_t RTAny::as_int64() const { + CHECK(type_ == RTAnyType::kI64Value); + return value_.i64_val; +} +uint64_t RTAny::as_uint64() const { + CHECK(type_ == RTAnyType::kU64Value); + return value_.u64_val; +} +int64_t RTAny::as_date32() const { + CHECK(type_ == RTAnyType::kDate32); + return value_.i64_val; +} + +double RTAny::as_double() const { + CHECK(type_ == RTAnyType::kF64Value); + return value_.f64_val; +} + +const std::pair& RTAny::as_vertex() const { + CHECK(type_ == RTAnyType::kVertex); + return value_.vertex; +} +const std::tuple& RTAny::as_edge() const { + CHECK(type_ == RTAnyType::kEdge); + return value_.edge; +} +const std::set& RTAny::as_string_set() const { + CHECK(type_ == RTAnyType::kStringSetValue); + return *value_.str_set; +} +std::string_view RTAny::as_string() const { + if (type_ == RTAnyType::kStringValue) { + return value_.str_val; + } else if (type_ == RTAnyType::kUnknown) { + return std::string_view(); + } else { + LOG(FATAL) << "unexpected type" << static_cast(type_.type_enum_); + return std::string_view(); + } +} + +List RTAny::as_list() const { + CHECK(type_ == RTAnyType::kList); + return value_.list; +} +const std::vector& RTAny::as_vertex_list() const { + CHECK(type_ == RTAnyType::kVertexSetValue); + return *value_.vset; +} + +Path RTAny::as_path() const { + CHECK(type_ == RTAnyType::kPath); + return value_.p; +} + +Tuple RTAny::as_tuple() const { + CHECK(type_ == RTAnyType::kTuple); + return value_.t; +} + +Map RTAny::as_map() const { + CHECK(type_ == RTAnyType::kMap); + return value_.map; +} + +int RTAny::numerical_cmp(const RTAny& other) const { + switch (type_.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + switch (other.type_.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI32Value: + return value_.i64_val - other.value_.i32_val; + case RTAnyType::RTAnyTypeImpl::kF64Value: + return value_.i64_val - other.value_.f64_val; + default: + LOG(FATAL) << "not support for " << static_cast(other.type_.type_enum_); + } + break; + case RTAnyType::RTAnyTypeImpl::kI32Value: + switch (other.type_.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return value_.i32_val - other.value_.i64_val; + case RTAnyType::RTAnyTypeImpl::kF64Value: + return value_.i32_val - other.value_.f64_val; + default: + LOG(FATAL) << "not support for " << static_cast(other.type_.type_enum_); + } + break; + case RTAnyType::RTAnyTypeImpl::kF64Value: + switch (other.type_.type_enum_) { + case RTAnyType::RTAnyTypeImpl::kI64Value: + return value_.f64_val - other.value_.i64_val; + case RTAnyType::RTAnyTypeImpl::kI32Value: + return value_.f64_val - other.value_.i32_val; + default: + LOG(FATAL) << "not support for " << static_cast(type_.type_enum_); + } + break; + default: + LOG(FATAL) << "not support for " << static_cast(type_.type_enum_); + return -1; + } +} + +inline static bool is_numerical_type(const RTAnyType& type) { + return type == RTAnyType::kI64Value || type == RTAnyType::kI32Value || + type == RTAnyType::kF64Value; +} + +bool RTAny::operator<(const RTAny& other) const { + if (type_.type_enum_ != other.type_.type_enum_) { + if (is_numerical_type(type_) && is_numerical_type(other.type_)) { + return numerical_cmp(other) < 0; + } else { + return false; + } + } + if (type_ == RTAnyType::kI64Value) { + return value_.i64_val < other.value_.i64_val; + + } else if (type_ == RTAnyType::kI32Value) { + return value_.i32_val < other.value_.i32_val; + + } else if (type_ == RTAnyType::kStringValue) { + return value_.str_val < other.value_.str_val; + } else if (type_ == RTAnyType::kDate32) { + return value_.i64_val < other.value_.i64_val; + } else if (type_ == RTAnyType::kF64Value) { + return value_.f64_val < other.value_.f64_val; + } + + LOG(FATAL) << "not support for " << static_cast(type_.type_enum_); + return true; +} + +bool RTAny::operator==(const RTAny& other) const { + // assert(type_ == other.type_); + if (type_.type_enum_ != other.type_.type_enum_) { + if (is_numerical_type(type_) && is_numerical_type(other.type_)) { + return numerical_cmp(other) == 0; + } else { + return false; + } + } + + if (type_ == RTAnyType::kI64Value) { + return value_.i64_val == other.value_.i64_val; + } else if (type_ == RTAnyType::kI32Value) { + return value_.i32_val == other.value_.i32_val; + } else if (type_ == RTAnyType::kStringValue) { + return value_.str_val == other.value_.str_val; + } else if (type_ == RTAnyType::kVertex) { + return value_.vertex == other.value_.vertex; + } else if (type_ == RTAnyType::kDate32) { + return value_.i64_val == other.value_.i64_val; + } + + if (type_ == RTAnyType::kI64Value && other.type_ == RTAnyType::kI32Value) { + return value_.i64_val == other.value_.i32_val; + } else if (type_ == RTAnyType::kI32Value && other.type_ == RTAnyType::kI64Value) { + return value_.i32_val == other.value_.i64_val; + } else if (type_ == RTAnyType::kF64Value) { + return value_.f64_val == other.value_.f64_val; + } + + LOG(FATAL) << "not support..." << static_cast(type_.type_enum_); + return true; +} + +RTAny RTAny::operator+(const RTAny& other) const { + if (type_ == RTAnyType::kI64Value && other.type_ == RTAnyType::kI32Value) { + return RTAny::from_int64(value_.i64_val + other.value_.i32_val); + } else if (type_ == RTAnyType::kI32Value && other.type_ == RTAnyType::kI64Value) { + return RTAny::from_int64(value_.i32_val * 1l + other.value_.i64_val); + } + if (type_ == RTAnyType::kF64Value) { + return RTAny::from_double(value_.f64_val + other.value_.f64_val); + } else if (type_ == RTAnyType::kI64Value) { + return RTAny::from_int64(value_.i64_val + other.value_.i64_val); + } else if (type_ == RTAnyType::kI32Value) { + return RTAny::from_int32(value_.i32_val + other.value_.i32_val); + } + + LOG(FATAL) << "not support" << static_cast(type_.type_enum_); + return RTAny(); +} + +RTAny RTAny::operator-(const RTAny& other) const { + // CHECK(type_ == other.type_); + + if (type_ == RTAnyType::kI64Value && other.type_ == RTAnyType::kI32Value) { + return RTAny::from_int64(value_.i64_val - other.value_.i32_val); + } else if (type_ == RTAnyType::kI32Value && other.type_ == RTAnyType::kI64Value) { + return RTAny::from_int64(value_.i32_val * 1l - other.value_.i64_val); + } + if (type_ == RTAnyType::kF64Value) { + return RTAny::from_double(value_.f64_val - other.value_.f64_val); + } else if (type_ == RTAnyType::kI64Value) { + return RTAny::from_int64(value_.i64_val - other.value_.i64_val); + } else if (type_ == RTAnyType::kI32Value) { + return RTAny::from_int32(value_.i32_val - other.value_.i32_val); + } + LOG(FATAL) << "not support"; + return RTAny(); +} + +RTAny RTAny::operator/(const RTAny& other) const { + // CHECK(type_ == other.type_); + + if (type_ == RTAnyType::kI64Value && other.type_ == RTAnyType::kI32Value) { + return RTAny::from_int64(value_.i64_val / other.value_.i32_val); + } else if (type_ == RTAnyType::kI32Value && other.type_ == RTAnyType::kI64Value) { + return RTAny::from_int64(value_.i32_val * 1l / other.value_.i64_val); + } + + if (type_ == RTAnyType::kI64Value) { + return RTAny::from_int64(value_.i64_val / other.value_.i64_val); + } else if (type_ == RTAnyType::kF64Value) { + return RTAny::from_double(value_.f64_val / other.value_.f64_val); + } else if (type_ == RTAnyType::kI32Value) { + return RTAny::from_int32(value_.i32_val / other.value_.i32_val); + } + LOG(FATAL) << "not support"; + return RTAny(); +} + +void RTAny::encode_sig(RTAnyType type, Encoder& encoder) const { + if (type == RTAnyType::kI64Value) { + encoder.put_long(this->as_int64()); + } else if (type == RTAnyType::kStringValue) { + encoder.put_string_view(this->as_string()); + } else if (type == RTAnyType::kI32Value) { + encoder.put_int(this->as_int32()); + } else if (type == RTAnyType::kVertex) { + const auto& v = this->value_.vertex; + encoder.put_byte(v.first); + encoder.put_int(v.second); + } else if (type == RTAnyType::kEdge) { + const auto& [label, src, dst, prop, dir] = this->as_edge(); + + encoder.put_byte(label.src_label); + encoder.put_byte(label.dst_label); + encoder.put_byte(label.edge_label); + encoder.put_int(src); + encoder.put_int(dst); + encoder.put_byte(dir == Direction::kOut ? 1 : 0); + + } else if (type == RTAnyType::kBoolValue) { + encoder.put_byte(this->as_bool() ? 1 : 0); + } else if (type == RTAnyType::kList) { + encoder.put_int(this->as_list().size()); + List list = this->as_list(); + for (size_t i = 0; i < list.size(); ++i) { + list.get(i).encode_sig(list.get(i).type(), encoder); + } + } else if (type == RTAnyType::kTuple) { + Tuple tuple = this->as_tuple(); + encoder.put_int(tuple.size()); + for (size_t i = 0; i < tuple.size(); ++i) { + tuple.get(i).encode_sig(tuple.get(i).type(), encoder); + } + } else if (type == RTAnyType::kNull) { + encoder.put_int(-1); + } else if (type == RTAnyType::kF64Value) { + encoder.put_double(this->as_double()); + } else { + LOG(FATAL) << "not implemented for " << static_cast(type_.type_enum_); + } +} + +std::string RTAny::to_string() const { + if (type_ == RTAnyType::kI64Value) { + return std::to_string(value_.i64_val); + } else if (type_ == RTAnyType::kStringValue) { + return std::string(value_.str_val); + } else if (type_ == RTAnyType::kI32Value) { + return std::to_string(value_.i32_val); + } else if (type_ == RTAnyType::kVertex) { +#if 0 + return std::string("v") + + std::to_string(static_cast(value_.vertex.first)) + "-" + + std::to_string(value_.vertex.second); +#else + return std::to_string(value_.vertex.second); +#endif + } else if (type_ == RTAnyType::kStringSetValue) { + std::string ret = "{"; + for (auto& str : *value_.str_set) { + ret += str; + ret += ", "; + } + ret += "}"; + return ret; + } else if (type_ == RTAnyType::kEdge) { + auto [label, src, dst, prop, dir] = value_.edge; + return std::to_string(src) + " -> " + std::to_string(dst); + } else if (type_ == RTAnyType::kPath) { + return value_.p.to_string(); + } else if (type_ == RTAnyType::kBoolValue) { + return value_.b_val ? "true" : "false"; + } else if (type_ == RTAnyType::kDate32) { + return std::to_string(value_.i64_val); + } else if (type_ == RTAnyType::kList) { + std::string ret = "["; + for (size_t i = 0; i < value_.list.size(); ++i) { + ret += value_.list.get(i).to_string(); + if (i != value_.list.size() - 1) { + ret += ", "; + } + } + ret += "]"; + return ret; + } else if (type_ == RTAnyType::kTuple) { + std::string ret = "("; + for (size_t i = 0; i < value_.t.size(); ++i) { + ret += value_.t.get(i).to_string(); + if (i != value_.t.size() - 1) { + ret += ", "; + } + } + ret += ")"; + return ret; + } else if (type_ == RTAnyType::kNull) { + return "null"; + } else if (type_ == RTAnyType::kF64Value) { + return std::to_string(value_.f64_val); + } else { + LOG(FATAL) << "not implemented for " << static_cast(type_.type_enum_); + return ""; + } +} + } // namespace runtime } // namespace gs diff --git a/flex/engines/graph_db/runtime/common/types.cc b/flex/engines/graph_db/runtime/common/types.cc deleted file mode 100644 index 4f0bf79a5b98..000000000000 --- a/flex/engines/graph_db/runtime/common/types.cc +++ /dev/null @@ -1,55 +0,0 @@ - -/** Copyright 2020 Alibaba Group Holding Limited. - * - * 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. - */ - -#include "flex/engines/graph_db/runtime/common/types.h" - -namespace gs { -namespace runtime { -uint64_t encode_unique_vertex_id(label_t label_id, vid_t vid) { - // encode label_id and vid to a unique vid - GlobalId global_id(label_id, vid); - return global_id.global_id; -} - -uint32_t generate_edge_label_id(label_t src_label_id, label_t dst_label_id, - label_t edge_label_id) { - uint32_t unique_edge_label_id = src_label_id; - static constexpr int num_bits = sizeof(label_t) * 8; - unique_edge_label_id = unique_edge_label_id << num_bits; - unique_edge_label_id = unique_edge_label_id | dst_label_id; - unique_edge_label_id = unique_edge_label_id << num_bits; - unique_edge_label_id = unique_edge_label_id | edge_label_id; - return unique_edge_label_id; -} - -int64_t encode_unique_edge_id(uint32_t label_id, vid_t src, vid_t dst) { - // We assume label_id is only used by 24 bits. - int64_t unique_edge_id = label_id; - static constexpr int num_bits = sizeof(int64_t) * 8 - sizeof(uint32_t) * 8; - unique_edge_id = unique_edge_id << num_bits; - // bitmask for top 44 bits set to 1 - int64_t bitmask = 0xFFFFFFFFFF000000; - // 24 bit | 20 bit | 20 bit - if (bitmask & (int64_t) src || bitmask & (int64_t) dst) { - LOG(ERROR) << "src or dst is too large to be encoded in 20 bits: " << src - << " " << dst; - } - unique_edge_id = unique_edge_id | (src << 20); - unique_edge_id = unique_edge_id | dst; - return unique_edge_id; -} -} // namespace runtime -} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/common/types.h b/flex/engines/graph_db/runtime/common/types.h index 28f2a5784bff..4ecbda48c1ed 100644 --- a/flex/engines/graph_db/runtime/common/types.h +++ b/flex/engines/graph_db/runtime/common/types.h @@ -80,6 +80,40 @@ struct LabelTriplet { label_t edge_label; }; +uint64_t encode_unique_vertex_id(label_t label_id, vid_t vid) { + // encode label_id and vid to a unique vid + GlobalId global_id(label_id, vid); + return global_id.global_id; +} + +uint32_t generate_edge_label_id(label_t src_label_id, label_t dst_label_id, + label_t edge_label_id) { + uint32_t unique_edge_label_id = src_label_id; + static constexpr int num_bits = sizeof(label_t) * 8; + unique_edge_label_id = unique_edge_label_id << num_bits; + unique_edge_label_id = unique_edge_label_id | dst_label_id; + unique_edge_label_id = unique_edge_label_id << num_bits; + unique_edge_label_id = unique_edge_label_id | edge_label_id; + return unique_edge_label_id; +} + +int64_t encode_unique_edge_id(uint32_t label_id, vid_t src, vid_t dst) { + // We assume label_id is only used by 24 bits. + int64_t unique_edge_id = label_id; + static constexpr int num_bits = sizeof(int64_t) * 8 - sizeof(uint32_t) * 8; + unique_edge_id = unique_edge_id << num_bits; + // bitmask for top 44 bits set to 1 + int64_t bitmask = 0xFFFFFFFFFF000000; + // 24 bit | 20 bit | 20 bit + if (bitmask & (int64_t) src || bitmask & (int64_t) dst) { + LOG(ERROR) << "src or dst is too large to be encoded in 20 bits: " << src + << " " << dst; + } + unique_edge_id = unique_edge_id | (src << 20); + unique_edge_id = unique_edge_id | dst; + return unique_edge_id; +} + } // namespace runtime } // namespace gs diff --git a/flex/tests/hqps/CMakeLists.txt b/flex/tests/hqps/CMakeLists.txt index fefe2f346cc2..feaf73f40334 100644 --- a/flex/tests/hqps/CMakeLists.txt +++ b/flex/tests/hqps/CMakeLists.txt @@ -7,5 +7,5 @@ foreach(f ${GS_TEST_FILES}) set(T_NAME ${CMAKE_MATCH_1}) message(STATUS "Found graphscope test - " ${T_NAME}) add_executable(${T_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/${T_NAME}.cc) - target_link_libraries(${T_NAME} flex_plan_proto flex_rt_mutable_graph flex_graph_db flex_utils ${GLOG_LIBRARIES} ${LIBGRAPELITE_LIBRARIES}) + target_link_libraries(${T_NAME} flex_plan_proto flex_rt_mutable_graph flex_graph_db flex_utils ${GLOG_LIBRARIES} ${LIBGRAPELITE_LIBRARIES}) endforeach()