flex/engines/hqps_db/core/utils/keyed.h (885 lines of code) (raw):

/** 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 ENGINES_HQPS_ENGINE_KEYED_UTILS_H_ #define ENGINES_HQPS_ENGINE_KEYED_UTILS_H_ #include "flex/engines/hqps_db/core/utils/props.h" #include "flex/engines/hqps_db/database/mutable_csr_interface.h" #include "flex/engines/hqps_db/structures/collection.h" #include "flex/engines/hqps_db/structures/multi_edge_set/adj_edge_set.h" #include "flex/engines/hqps_db/structures/multi_edge_set/untyped_edge_set.h" #include "flex/engines/hqps_db/structures/multi_vertex_set/general_vertex_set.h" #include "flex/engines/hqps_db/structures/multi_vertex_set/keyed_row_vertex_set.h" #include "flex/engines/hqps_db/structures/multi_vertex_set/row_vertex_set.h" #include "flex/engines/hqps_db/structures/multi_vertex_set/two_label_vertex_set.h" #include "flex/engines/hqps_db/structures/path.h" namespace gs { template <typename SET_T> struct AggFirst; template <typename T> struct AggFirst<Collection<T>> { using result_t = Collection<T>; }; template <typename LabelT, typename VID_T, typename... T> struct AggFirst<RowVertexSetImpl<LabelT, VID_T, T...>> { using result_t = RowVertexSetImpl<LabelT, VID_T, T...>; }; template <typename VID_T, typename LabelT, typename... T> struct AggFirst<TwoLabelVertexSetImpl<VID_T, LabelT, T...>> { using result_t = TwoLabelVertexSetImpl<VID_T, LabelT, T...>; }; template <typename VID_T, typename LabelT, typename... T> struct AggFirst<GeneralVertexSet<VID_T, LabelT, T...>> { using result_t = GeneralVertexSet<VID_T, LabelT, T...>; }; /// @brief Helper to get keyed set type /// @tparam T /// @tparam ValueT Keyed prop type template <typename T, typename KEY_ALIAS_T> struct KeyedT; // group by the vertex set itself template <typename LabelT, typename VID_T, typename... T> struct KeyedT<RowVertexSet<LabelT, VID_T, T...>, PropertySelector<grape::EmptyType>> { using keyed_set_t = KeyedRowVertexSet<LabelT, VID_T, VID_T, T...>; // // The builder type. using keyed_builder_t = KeyedRowVertexSetBuilder<LabelT, VID_T, VID_T, T...>; using unkeyed_builder_t = RowVertexSetBuilder<LabelT, VID_T, T...>; static keyed_builder_t create_keyed_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const PropertySelector<grape::EmptyType>& selector) { return keyed_builder_t(set); } static unkeyed_builder_t create_unkeyed_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const PropertySelector<grape::EmptyType>& selector) { return set.CreateBuilder(); } }; // Group By TwoLabelVertexSet's internal id. template <typename LabelT, typename VID_T, typename... T> struct KeyedT<TwoLabelVertexSet<VID_T, LabelT, T...>, PropertySelector<grape::EmptyType>> { using keyed_set_t = TwoLabelVertexSet<VID_T, LabelT, T...>; // // The builder type. using keyed_builder_t = TwoLabelVertexSetImplKeyedBuilder<VID_T, LabelT, T...>; using unkeyed_builder_t = TwoLabelVertexSetImplBuilder<VID_T, LabelT, T...>; static keyed_builder_t create_keyed_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const PropertySelector<grape::EmptyType>& selector) { return keyed_builder_t(set); } static unkeyed_builder_t create_unkeyed_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const PropertySelector<grape::EmptyType>& selector) { return set.CreateBuilder(); } }; // Group By TwoLabelVertexSet's other properties template <typename LabelT, typename VID_T, typename... T, typename PropT> struct KeyedT<TwoLabelVertexSet<VID_T, LabelT, T...>, PropertySelector<PropT>> { using keyed_set_t = Collection<PropT>; // // The builder type. using keyed_builder_t = KeyedCollectionBuilder<PropT>; using unkeyed_builder_t = CollectionBuilder<PropT>; static keyed_builder_t create_keyed_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const PropertySelector<PropT>& selector) { return keyed_builder_t(); } static unkeyed_builder_t create_unkeyed_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const PropertySelector<grape::EmptyType>& selector) { return unkeyed_builder_t(); } }; // group by the vertex set' property template <typename LabelT, typename VID_T, typename... T, typename PropT> struct KeyedT<RowVertexSet<LabelT, VID_T, T...>, PropertySelector<PropT>> { using keyed_set_t = Collection<PropT>; // // The builder type. using keyed_builder_t = KeyedCollectionBuilder<PropT>; using unkeyed_builder_t = CollectionBuilder<PropT>; static keyed_builder_t create_keyed_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const PropertySelector<PropT>& selector) { return keyed_builder_t(set); } static unkeyed_builder_t create_unkeyed_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const PropertySelector<PropT>& selector) { return unkeyed_builder_t(); } }; // key on a keyed row vertex get us a unkeyed set. template <typename LabelT, typename KEY_T, typename VID_T, typename... SET_T> struct KeyedT<KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T, SET_T...>, PropertySelector<grape::EmptyType>> { using keyed_set_t = KeyedRowVertexSetImpl<LabelT, VID_T, SET_T...>; // // The builder type. using keyed_builder_t = KeyedRowVertexSetBuilder<LabelT, KEY_T, VID_T, SET_T...>; using unkeyed_builder_t = typename KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T, SET_T...>::builder_t; static keyed_builder_t create_keyed_builder( const KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T, SET_T...>& set, const PropertySelector<grape::EmptyType>& selector) { return builder_t(set); } static unkeyed_builder_t create_unkeyedkeyed_builder( const KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T, SET_T...>& set, const PropertySelector<grape::EmptyType>& selector) { return set.CreateBuilder(); } }; // group by vertex set' id, for generate vertex set. template <typename VID_T, typename LabelT, typename... T> struct KeyedT<GeneralVertexSet<VID_T, LabelT, T...>, PropertySelector<grape::EmptyType>> { using keyed_builder_t = GeneralVertexSetKeyedBuilder<VID_T, LabelT, T...>; using keyed_set_t = GeneralVertexSet<VID_T, LabelT, T...>; using unkeyed_builder_t = typename GeneralVertexSet<LabelT, VID_T, LabelT, T...>::builder_t; static keyed_builder_t create_keyed_builder( const GeneralVertexSet<VID_T, LabelT, T...>& set, const PropertySelector<grape::EmptyType>& selector) { return keyed_builder_t(set); } static unkeyed_builder_t create_unkeyedkeyed_builder( const GeneralVertexSet<VID_T, LabelT, T...>& set, const PropertySelector<grape::EmptyType>& selector) { return set.CreateBuilder(); } }; template <typename VID_T, typename LabelT, typename... T> struct KeyedT<GeneralVertexSet<VID_T, LabelT, T...>, PropertySelector<LabelKey>> { using keyed_set_t = Collection<LabelKey>; using keyed_builder_t = KeyedCollectionBuilder<LabelKey>; static keyed_builder_t create_keyed_builder( const GeneralVertexSet<VID_T, LabelT, T...>& set, const PropertySelector<LabelKey>& selector) { return keyed_builder_t(); } }; template <typename T> struct KeyedT<Collection<T>, PropertySelector<grape::EmptyType>> { using keyed_set_t = Collection<T>; // // The builder type. using keyed_builder_t = KeyedCollectionBuilder<T>; using unkeyed_builder_t = CollectionBuilder<T>; static keyed_builder_t create_keyed_builder( const Collection<T>& set, const PropertySelector<grape::EmptyType>& selector) { return keyed_builder_t(set); } static unkeyed_builder_t create_unkeyed_builder( const Collection<T>& set, const PropertySelector<grape::EmptyType>& selector) { return unkeyed_builder_t(); } }; // when keyed with aggregation function, (which we currently only support // collection) /// @brief Helper to get keyed set type with aggregation func /// @tparam T /// @tparam ValueT Keyed prop type template <typename GI, typename T, AggFunc agg_func, typename Props, typename Tags> struct KeyedAggT; /// @brief Helper to get keyed set type with aggregation func, which is applied /// on multiple column /// @tparam T /// @tparam ValueT Keyed prop type template <typename GI, typename SET_TUPLE_T, AggFunc agg_func, typename Props, typename Tags> struct KeyedAggMultiColT; template <typename GI, typename LabelT, typename VID_T, typename... T, typename PropT, int tag_id> struct KeyedAggT<GI, RowVertexSet<LabelT, VID_T, T...>, AggFunc::COUNT, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using index_ele_t = typename RowVertexSet<LabelT, VID_T, T...>::index_ele_tuple_t; using prop_getter_t = RowVertexSetPropGetter< tag_id, gs::mutable_csr_graph_impl::SinglePropGetter<PropT>, index_ele_t>; // build a counter array. using aggregate_res_builder_t = PropCountBuilder<tag_id, prop_getter_t>; static aggregate_res_builder_t create_agg_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selector) { auto prop_getter = create_prop_getter_impl<tag_id, PropT>( set, graph, std::get<0>(selector).prop_name_); return aggregate_res_builder_t(std::move(prop_getter)); } }; template <typename GI, typename LabelT, typename VID_T, typename... T, int tag_id> struct KeyedAggT<GI, RowVertexSet<LabelT, VID_T, T...>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; // build a counter array. using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selector) { return CountBuilder<tag_id>(); } }; // aggregate count_dist template <typename GI, typename LabelT, typename VID_T, typename... T, int tag_id> struct KeyedAggT<GI, RowVertexSet<LabelT, VID_T, T...>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<int64_t>; // build a counter array. using vertex_set_t = RowVertexSet<LabelT, VID_T, T...>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, vertex_set_t>; static aggregate_res_builder_t create_agg_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set.GetVertices()); } }; template <typename GI, typename LabelT, typename VID_T, typename... T, int tag_id> struct KeyedAggT<GI, GeneralVertexSet<VID_T, LabelT, T...>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<int64_t>; // build a counter array. using vertex_set_t = GeneralVertexSet<VID_T, LabelT, T...>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, vertex_set_t>; static aggregate_res_builder_t create_agg_builder( const vertex_set_t& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set.GetBitsets(), set.GetLabels()); } }; template <typename GI, typename VID_T, typename LabelT, typename... T, typename PropT, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, T...>, AggFunc::COUNT, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<int64_t>; using index_ele_t = typename TwoLabelVertexSet<VID_T, LabelT, T...>::index_ele_tuple_t; // build a counter array. using prop_getter_t = TwoLabelVertexSetImplPropGetter< tag_id, gs::mutable_csr_graph_impl::SinglePropGetter<PropT>, index_ele_t>; using aggregate_res_builder_t = PropCountBuilder<tag_id, prop_getter_t>; static aggregate_res_builder_t create_agg_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { auto prop_getter = create_prop_getter_impl<tag_id, PropT>( set, graph, std::get<0>(selectors).prop_name_); return aggregate_res_builder_t(std::move(prop_getter)); } }; template <typename GI, typename VID_T, typename LabelT, typename... T, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, T...>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<int64_t>; // build a counter array. using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return CountBuilder<tag_id>(); } }; // count distinct for two_label set. template <typename GI, typename VID_T, typename LabelT, typename... T, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, T...>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<int64_t>; // build a counter array. using vertex_set_t = TwoLabelVertexSet<VID_T, LabelT, T...>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, vertex_set_t>; static aggregate_res_builder_t create_agg_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set.GetBitset(), set.GetVertices()); } }; // general vertex set to_count template <typename GI, typename VID_T, typename LabelT, typename... SET_T, typename PropT, int tag_id> struct KeyedAggT<GI, GeneralVertexSet<VID_T, LabelT, SET_T...>, AggFunc::COUNT, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<int64_t>; using index_ele_t = typename GeneralVertexSet<VID_T, LabelT, SET_T...>::index_ele_tuple_t; using prop_getter_t = GeneralVertexSetPropGetter< tag_id, gs::mutable_csr_graph_impl::SinglePropGetter<PropT>, index_ele_t>; // build a counter array. using aggregate_res_builder_t = PropCountBuilder<tag_id, prop_getter_t>; static aggregate_res_builder_t create_agg_builder( const GeneralVertexSet<VID_T, LabelT, SET_T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { auto prop_getter = create_prop_getter_impl<tag_id, PropT>( set, graph, std::get<0>(selectors).prop_name_); return aggregate_res_builder_t(std::move(prop_getter)); } }; // count internal for general vertex set. template <typename GI, typename VID_T, typename LabelT, typename... SET_T, int tag_id> struct KeyedAggT<GI, GeneralVertexSet<VID_T, LabelT, SET_T...>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<int64_t>; // build a counter array. using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const GeneralVertexSet<VID_T, LabelT, SET_T...>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return CountBuilder<tag_id>(); } }; template <typename GI, typename T, int tag_id> struct KeyedAggT<GI, Collection<T>, AggFunc::SUM, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<T>; using prop_getter_t = CollectionPropGetter<tag_id, T>; // build a counter array. using aggregate_res_builder_t = SumBuilder<prop_getter_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const Collection<T>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(prop_getter_t()); } }; template <typename GI, typename VID_T, typename LabelT, typename... SET_T, typename PropT, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, SET_T...>, AggFunc::SUM, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using index_ele_t = typename TwoLabelVertexSet<VID_T, LabelT, SET_T...>::index_ele_tuple_t; using prop_getter_t = TwoLabelVertexSetImplPropGetter< tag_id, gs::mutable_csr_graph_impl::SinglePropGetter<PropT>, index_ele_t>; using aggregate_res_builder_t = SumBuilder<prop_getter_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const TwoLabelVertexSet<VID_T, LabelT, SET_T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(create_prop_getter_impl<tag_id, PropT>( set, graph, std::get<0>(selectors).prop_name_)); } }; template <typename GI, typename LabelT, typename VID_T, typename... T, typename PropT, int tag_id> struct KeyedAggT<GI, RowVertexSet<LabelT, VID_T, T...>, AggFunc::TO_SET, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = CollectionOfVec<PropT>; using aggregate_res_builder_t = CollectionOfSetBuilder<PropT, GI, RowVertexSet<LabelT, VID_T, T...>, tag_id>; static aggregate_res_builder_t create_agg_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return CollectionOfSetBuilder<PropT, GI, RowVertexSet<LabelT, VID_T, T...>, tag_id>( set, graph, std::array{std::get<0>(selectors).prop_name_}); } }; // to_vector template <typename GI, typename T, typename PropT, int tag_id> struct KeyedAggT<GI, Collection<T>, AggFunc::TO_LIST, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = CollectionOfVec<PropT>; using aggregate_res_builder_t = CollectionOfVecBuilder<T, GI, Collection<T>, tag_id>; static aggregate_res_builder_t create_agg_builder( const Collection<T>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t( graph, set, std::array{std::get<0>(selectors).prop_name_}); } }; template <typename GI, typename LabelT, typename VID_T, typename... T, typename PropT, int tag_id> struct KeyedAggT<GI, RowVertexSet<LabelT, VID_T, T...>, AggFunc::TO_LIST, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { static_assert(!std::is_same_v<PropT, grape::EmptyType>, "Aggregate to_list for vertex set it self is not allowed"); using agg_res_t = CollectionOfVec<PropT>; using aggregate_res_builder_t = CollectionOfVecBuilder<PropT, GI, RowVertexSet<LabelT, VID_T, T...>, tag_id>; static aggregate_res_builder_t create_agg_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(set, graph, {std::get<0>(selectors).prop_name_}); } }; // Aggregate to_list for twolabel vertex set's internal id. template <typename GI, typename LabelT, typename VID_T, typename... T, int tag_id> struct KeyedAggT<GI, RowVertexSet<LabelT, VID_T, T...>, AggFunc::TO_LIST, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = CollectionOfVec<GlobalId>; using aggregate_res_builder_t = CollectionOfVecBuilder<grape::EmptyType, GI, RowVertexSet<LabelT, VID_T, T...>, tag_id>; static aggregate_res_builder_t create_agg_builder( const RowVertexSet<LabelT, VID_T, T...>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set.GetLabel()); } }; template <typename GI, typename LabelT, typename VID_T, typename... T, typename PropT, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, T...>, AggFunc::TO_LIST, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = CollectionOfVec<PropT>; using aggregate_res_builder_t = CollectionOfVecBuilder<PropT, GI, TwoLabelVertexSet<VID_T, LabelT, T...>, tag_id>; static aggregate_res_builder_t create_agg_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(set, graph, {std::get<0>(selectors).prop_name_}); } }; template <typename GI, typename LabelT, typename VID_T, typename... T, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, T...>, AggFunc::TO_LIST, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = CollectionOfVec<GlobalId>; using aggregate_res_builder_t = CollectionOfVecBuilder<grape::EmptyType, GI, TwoLabelVertexSet<VID_T, LabelT, T...>, tag_id>; static aggregate_res_builder_t create_agg_builder( const TwoLabelVertexSet<VID_T, LabelT, T...>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set.GetLabels()); } }; // get min template <typename GI, typename PropT, int tag_id> struct KeyedAggT<GI, Collection<PropT>, AggFunc::MIN, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using PropGetterT = CollectionPropGetter<tag_id, PropT>; using aggregate_res_builder_t = MinBuilder<GI, PropGetterT, tag_id>; static aggregate_res_builder_t create_agg_builder( const Collection<PropT>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(PropGetterT()); } }; template <typename GI, typename VID_T, typename LabelT, typename... SET_T, typename PropT, int tag_id> struct KeyedAggT<GI, RowVertexSet<LabelT, VID_T, SET_T...>, AggFunc::MIN, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using index_ele_t = typename RowVertexSet<LabelT, VID_T, SET_T...>::index_ele_tuple_t; using prop_getter_t = RowVertexSetPropGetter< tag_id, gs::mutable_csr_graph_impl::SinglePropGetter<PropT>, index_ele_t>; using aggregate_res_builder_t = MinBuilder<GI, prop_getter_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const RowVertexSet<LabelT, VID_T, SET_T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(create_prop_getter_impl<tag_id, PropT>( set, graph, std::get<0>(selectors).prop_name_)); } }; template <typename GI, typename VID_T, typename LabelT, typename... SET_T, typename PropT, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, SET_T...>, AggFunc::MIN, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using index_ele_t = typename TwoLabelVertexSet<VID_T, LabelT, SET_T...>::index_ele_tuple_t; using prop_getter_t = TwoLabelVertexSetImplPropGetter< tag_id, gs::mutable_csr_graph_impl::SinglePropGetter<PropT>, index_ele_t>; using aggregate_res_builder_t = MinBuilder<GI, prop_getter_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const TwoLabelVertexSet<VID_T, LabelT, SET_T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(create_prop_getter_impl<tag_id, PropT>( set, graph, std::get<0>(selectors).prop_name_)); } }; // get max template <typename GI, typename PropT, int tag_id> struct KeyedAggT<GI, Collection<PropT>, AggFunc::MAX, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using prop_getter_t = CollectionPropGetter<tag_id, PropT>; using aggregate_res_builder_t = MaxBuilder<GI, prop_getter_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const Collection<PropT>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(prop_getter_t()); } }; template <typename GI, typename LabelT, typename VID_T, typename... SET_T, typename PropT, int tag_id> struct KeyedAggT<GI, RowVertexSet<LabelT, VID_T, SET_T...>, AggFunc::MAX, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using index_ele_t = typename RowVertexSet<LabelT, VID_T, SET_T...>::index_ele_tuple_t; using prop_getter_t = RowVertexSetPropGetter< tag_id, gs::mutable_csr_graph_impl::SinglePropGetter<PropT>, index_ele_t>; using aggregate_res_builder_t = MaxBuilder<GI, prop_getter_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const RowVertexSet<LabelT, VID_T, SET_T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(create_prop_getter_impl<tag_id, PropT>( set, graph, std::get<0>(selectors).prop_name_)); } }; template <typename GI, typename LabelT, typename VID_T, typename... SET_T, typename PropT, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, SET_T...>, AggFunc::MAX, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using index_ele_t = typename TwoLabelVertexSet<VID_T, LabelT, SET_T...>::index_ele_tuple_t; using prop_getter_t = TwoLabelVertexSetImplPropGetter< tag_id, gs::mutable_csr_graph_impl::SinglePropGetter<PropT>, index_ele_t>; using aggregate_res_builder_t = MaxBuilder<GI, prop_getter_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const TwoLabelVertexSet<VID_T, LabelT, SET_T...>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(create_prop_getter_impl<tag_id, PropT>( set, graph, std::get<0>(selectors).prop_name_)); } }; template <typename GI, typename T, typename PropT, int tag_id> struct KeyedAggT<GI, Collection<T>, AggFunc::FIRST, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<T>; using aggregate_res_builder_t = FirstBuilder<GI, Collection<T>, PropT, tag_id>; static aggregate_res_builder_t create_agg_builder( const Collection<T>& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(set, graph, {std::get<0>(selectors).prop_name_}); } }; // Aggregate first for twolabel vertex set template <typename GI, typename VID_T, typename LabelT, typename... T, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSetImpl<VID_T, LabelT, T...>, AggFunc::FIRST, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = TwoLabelVertexSetImpl<VID_T, LabelT, T...>; using old_set_t = TwoLabelVertexSetImpl<VID_T, LabelT, T...>; using aggregate_res_builder_t = FirstBuilder<GI, TwoLabelVertexSetImpl<VID_T, LabelT, T...>, grape::EmptyType, tag_id>; static aggregate_res_builder_t create_agg_builder( const old_set_t& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t( set, graph, std::array{std::get<0>(selectors).prop_name_}); } }; // Aggregate first for general vertex set template <typename GI, typename VID_T, typename LabelT, typename... T, int tag_id> struct KeyedAggT<GI, GeneralVertexSet<VID_T, LabelT, T...>, AggFunc::FIRST, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = GeneralVertexSet<VID_T, LabelT, T...>; using old_set_t = GeneralVertexSet<VID_T, LabelT, T...>; using aggregate_res_builder_t = FirstBuilder<GI, GeneralVertexSet<VID_T, LabelT, T...>, grape::EmptyType, tag_id>; static aggregate_res_builder_t create_agg_builder( const old_set_t& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t( set, graph, std::array{std::get<0>(selectors).prop_name_}); } }; template <typename GI, typename VID_T, typename LabelT, int tag_id> struct KeyedAggT<GI, UnTypedEdgeSet<VID_T, LabelT, typename GI::sub_graph_t>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const UnTypedEdgeSet<VID_T, LabelT, typename GI::sub_graph_t>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return CountBuilder<tag_id>(); } }; template <typename GI, typename VID_T, typename LabelT, typename SET_T, int tag_id> struct KeyedAggT<GI, SingleLabelEdgeSet<VID_T, LabelT, SET_T>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const SingleLabelEdgeSet<VID_T, LabelT, SET_T>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return CountBuilder<tag_id>(); } }; template <typename GI, typename VID_T, typename LabelT, typename EDATA_T, int tag_id> struct KeyedAggT<GI, FlatEdgeSet<VID_T, LabelT, EDATA_T>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const FlatEdgeSet<VID_T, LabelT, EDATA_T>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return CountBuilder<tag_id>(); } }; template <typename GI, typename VID_T, typename LabelT, int tag_id> struct KeyedAggT<GI, CompressedPathSet<VID_T, LabelT>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const CompressedPathSet<VID_T, LabelT>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return CountBuilder<tag_id>(); } }; template <typename GI, typename VID_T, typename LabelT, int tag_id> struct KeyedAggT<GI, PathSet<VID_T, LabelT>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const PathSet<VID_T, LabelT>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return CountBuilder<tag_id>(); } }; template <typename GI, typename T, int tag_id> struct KeyedAggT<GI, Collection<T>, AggFunc::COUNT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using aggregate_res_builder_t = CountBuilder<tag_id>; static aggregate_res_builder_t create_agg_builder( const Collection<T>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return CountBuilder<tag_id>(); } }; // COUNT DISTINCT for EdgeSets. template <typename GI, typename VID_T, typename LabelT, int tag_id> struct KeyedAggT<GI, UnTypedEdgeSet<VID_T, LabelT, typename GI::sub_graph_t>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using edge_set_t = UnTypedEdgeSet<VID_T, LabelT, typename GI::sub_graph_t>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, edge_set_t>; static aggregate_res_builder_t create_agg_builder( const UnTypedEdgeSet<VID_T, LabelT, typename GI::sub_graph_t>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set); } }; template <typename GI, typename VID_T, typename LabelT, typename SET_T, int tag_id> struct KeyedAggT<GI, SingleLabelEdgeSet<VID_T, LabelT, SET_T>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using edge_set_t = SingleLabelEdgeSet<VID_T, LabelT, SET_T>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, edge_set_t>; static aggregate_res_builder_t create_agg_builder( const SingleLabelEdgeSet<VID_T, LabelT, SET_T>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set); } }; template <typename GI, typename VID_T, typename LabelT, typename EDATA_T, int tag_id> struct KeyedAggT<GI, FlatEdgeSet<VID_T, LabelT, EDATA_T>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using edge_set_t = FlatEdgeSet<VID_T, LabelT, EDATA_T>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, edge_set_t>; static aggregate_res_builder_t create_agg_builder( const FlatEdgeSet<VID_T, LabelT, EDATA_T>& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set); } }; template <typename GI, typename VID_T, typename LabelT, int tag_id> struct KeyedAggT<GI, CompressedPathSet<VID_T, LabelT>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using path_set_t = CompressedPathSet<VID_T, LabelT>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, path_set_t>; static aggregate_res_builder_t create_agg_builder( const path_set_t& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set); } }; template <typename GI, typename VID_T, typename LabelT, int tag_id> struct KeyedAggT<GI, PathSet<VID_T, LabelT>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using path_set_t = PathSet<VID_T, LabelT>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, path_set_t>; static aggregate_res_builder_t create_agg_builder( const path_set_t& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set); } }; template <typename GI, typename T, int tag_id> struct KeyedAggT<GI, Collection<T>, AggFunc::COUNT_DISTINCT, std::tuple<grape::EmptyType>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<size_t>; using set_t = Collection<T>; using aggregate_res_builder_t = DistinctCountBuilder<tag_id, set_t>; static aggregate_res_builder_t create_agg_builder( const set_t& set, const GI& graph, std::tuple<PropertySelector<grape::EmptyType>>& selectors) { return aggregate_res_builder_t(set); } }; // aggregate average. template <typename GI, typename VID_T, typename LabelT, typename... SET_T, typename PropT, int tag_id> struct KeyedAggT<GI, RowVertexSetImpl<LabelT, VID_T, SET_T...>, AggFunc::AVG, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using set_t = RowVertexSetImpl<LabelT, VID_T, SET_T...>; using aggregate_res_builder_t = AvgBuilder<PropT, GI, set_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const set_t& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(set, graph, {std::get<0>(selectors).prop_name_}); } }; template <typename GI, typename VID_T, typename LabelT, typename... SET_T, typename PropT, int tag_id> struct KeyedAggT<GI, TwoLabelVertexSet<VID_T, LabelT, SET_T...>, AggFunc::AVG, std::tuple<PropT>, std::integer_sequence<int32_t, tag_id>> { using agg_res_t = Collection<PropT>; using set_t = TwoLabelVertexSet<VID_T, LabelT, SET_T...>; using aggregate_res_builder_t = AvgBuilder<PropT, GI, set_t, tag_id>; static aggregate_res_builder_t create_agg_builder( const set_t& set, const GI& graph, std::tuple<PropertySelector<PropT>>& selectors) { return aggregate_res_builder_t(set, graph, {std::get<0>(selectors).prop_name_}); } }; template <typename GI, typename... SET_T, typename... PropSelectorT, int... tag_ids> struct KeyedAggMultiColT<GI, std::tuple<SET_T...>, AggFunc::COUNT_DISTINCT, std::tuple<PropSelectorT...>, std::integer_sequence<int32_t, tag_ids...>> { using agg_res_t = Collection<size_t>; // get the tuple of sets from the tuple of tags. using aggregate_res_builder_t = MultiColDistinctCountBuilder<std::tuple<SET_T...>, tag_ids...>; static aggregate_res_builder_t create_agg_builder( const std::tuple<SET_T...>& set, const GI& graph, std::tuple<PropSelectorT...>& selectors) { return aggregate_res_builder_t(); } }; template <typename GI, typename... SET_T, typename... PropSelectorT, int... tag_ids> struct KeyedAggMultiColT<GI, std::tuple<SET_T...>, AggFunc::COUNT, std::tuple<PropSelectorT...>, std::integer_sequence<int32_t, tag_ids...>> { using agg_res_t = Collection<size_t>; // get the tuple of sets from the tuple of tags. using aggregate_res_builder_t = MultiColCountBuilder<tag_ids...>; static aggregate_res_builder_t create_agg_builder( const std::tuple<SET_T...>& set, const GI& graph, std::tuple<PropSelectorT...>& selectors) { return aggregate_res_builder_t(); } }; template <typename LabelT, typename KEY_T, typename VID_T, typename... T, typename ELE, typename DATA> static inline auto insert_into_builder_v2_impl( KeyedRowVertexSetBuilderImpl<LabelT, KEY_T, VID_T, T...>& builder, const ELE& ele, const DATA& data) { return builder.insert(ele, data); } template <typename LabelT, typename KEY_T, typename VID_T, typename ELE, typename DATA> static inline auto insert_into_builder_v2_impl( KeyedRowVertexSetBuilderImpl<LabelT, KEY_T, VID_T, grape::EmptyType>& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } // insert_into_bulder_v2_impl template < typename BuilderT, typename ELE, typename DATA, typename std::enable_if< (BuilderT::is_row_vertex_set_builder && std::is_same_v<DATA, std::tuple<grape::EmptyType>>)>::type* = nullptr> static inline auto insert_into_builder_v2_impl(BuilderT& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } // insert_into_bulder_v2_impl template < typename BuilderT, typename ELE, typename DATA, typename std::enable_if< (BuilderT::is_row_vertex_set_builder && !std::is_same_v<DATA, std::tuple<grape::EmptyType>>)>::type* = nullptr> static inline auto insert_into_builder_v2_impl(BuilderT& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele, data); } // insert into general vertex set builder template <typename BuilderT, typename ELE, typename DATA, typename std::enable_if< (BuilderT::is_general_vertex_set_builder)>::type* = nullptr> static inline auto insert_into_builder_v2_impl(BuilderT& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele, data); } template <typename VID_T, typename LabelT, typename EDATA_T, typename ELE, typename DATA> static inline auto insert_into_builder_v2_impl( FlatEdgeSetBuilder<VID_T, LabelT, EDATA_T>& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } template <typename BuilderT, typename ELE, typename DATA, typename std::enable_if< (BuilderT::is_general_edge_set_builder)>::type* = nullptr> static inline auto insert_into_builder_v2_impl(BuilderT& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } template < typename BuilderT, typename ELE, typename DATA, typename std::enable_if< (BuilderT::is_two_label_set_builder && std::is_same_v<DATA, std::tuple<grape::EmptyType>>)>::type* = nullptr> static inline auto insert_into_builder_v2_impl(BuilderT& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } template < typename BuilderT, typename ELE, typename DATA, typename std::enable_if< (BuilderT::is_two_label_set_builder && !std::is_same_v<DATA, std::tuple<grape::EmptyType>>)>::type* = nullptr> static inline auto insert_into_builder_v2_impl(BuilderT& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele, data); } // insert for collectionBuilder template < typename BuilderT, typename ELE, typename DATA, typename std::enable_if<(BuilderT::is_collection_builder)>::type* = nullptr> static inline auto insert_into_builder_v2_impl(BuilderT& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } // insert for adjEdgeSetBuilder template <typename ELE, typename DATA, typename GI, typename LabelT, typename VID_T, typename... EDATA_T> static inline auto insert_into_builder_v2_impl( AdjEdgeSetBuilder<GI, LabelT, VID_T, EDATA_T...>& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } template <typename ELE, typename DATA, typename GI, typename LabelT, typename VID_T> static inline auto insert_into_builder_v2_impl( AdjEdgeSetBuilder<GI, LabelT, VID_T, grape::EmptyType>& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } // insert to single label edge label. template <typename ELE, typename DATA, typename LabelT, typename VID_T, typename EDATA_T> static inline auto insert_into_builder_v2_impl( SingleLabelEdgeSetBuilder<VID_T, LabelT, EDATA_T>& builder, const ELE& ele, const DATA& data) { return builder.Insert(ele); } } // namespace gs #endif // ENGINES_HQPS_ENGINE_KEYED_UTILS_H_