flex/engines/hqps_db/core/utils/props.h (997 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_OPERATOR_PROP_UTILS_H_
#define ENGINES_HQPS_ENGINE_OPERATOR_PROP_UTILS_H_
#include <array>
#include <string>
#include <tuple>
#include <vector>
#include "grape/utils/bitset.h"
namespace gs {
// forward declare context
template <typename HEAD_T, int cur_alias, int base_tag, typename... ALIAS_SETS>
class Context;
// forward declare flat_edge_set
template <typename VID_T, typename LabelT, typename T>
class FlatEdgeSet;
template <typename VID_T, typename LabelT, typename EDATA_T>
class SingleLabelEdgeSet;
// forward declare general_edge_set
template <size_t N, typename GI, typename VID_T, typename LabelT, typename... T>
class GeneralEdgeSet;
// UntypedEdgeSet
template <typename VID_T, typename LabelT, typename SUB_GRAPH_T>
class UnTypedEdgeSet;
// forward declare keyed_row_vertex_set
template <typename LabelT, typename KEY_T, typename VID_T, typename... T>
class KeyedRowVertexSetImpl;
// forward declare row_vertex_set
template <typename LabelT, typename VID_T, typename... T>
class RowVertexSetImpl;
// forward declare two_label_vertex_set
template <typename VID_T, typename LabelT, typename... T>
class TwoLabelVertexSetImpl;
template <typename VID_T, typename LabelT, typename... SET_T>
class GeneralVertexSet;
template <typename GI, typename PropTupleT>
struct MultiPropGetterT;
template <typename GI, typename... T>
struct MultiPropGetterT<GI, std::tuple<T...>> {};
template <typename T>
class Collection;
template <typename GRAPH_INTERFACE, typename LabelT, typename... T>
static auto get_prop_getter_from_named_property(
const GRAPH_INTERFACE& graph, const LabelT& label,
const std::tuple<NamedProperty<T>...>& named_property) {
std::array<std::string, sizeof...(T)> prop_names;
int i = 0;
std::apply(
[&prop_names, &i](auto&... named_prop) {
((prop_names[i++] = named_prop.name), ...);
},
named_property);
return graph.template GetMultiPropGetter<T...>(label, prop_names);
}
//// Get one property getter for one label
template <typename GRAPH_INTERFACE, typename LabelT, typename... PropT>
static auto get_prop_getter_from_selectors(
const GRAPH_INTERFACE& graph, const LabelT& label,
const std::tuple<PropertySelector<PropT>...>& selectors) {
std::array<std::string, sizeof...(PropT)> prop_names;
int i = 0;
std::apply(
[&prop_names, &i](auto&... named_prop) {
((prop_names[i++] = named_prop.prop_name_), ...);
},
selectors);
return graph.template GetMultiPropGetter<PropT...>(label, prop_names);
}
/// get single property getter for one label
template <typename GRAPH_INTERFACE, typename LabelT, typename PropT>
static auto get_single_prop_getter_from_selector(
const GRAPH_INTERFACE& graph, const LabelT& label,
const PropertySelector<PropT>& selector) {
auto prop_name = selector.prop_name_;
return graph.template GetSinglePropGetter<PropT>(label, prop_name);
}
// Get prop getters from Selector.
template <typename GRAPH_INTERFACE, typename LabelT, size_t num_labels,
typename... SELECTOR, size_t... Is>
static auto get_prop_getters_from_selectors_impl(
const GRAPH_INTERFACE& graph, const std::array<LabelT, num_labels>& labels,
std::tuple<SELECTOR...> selectors, std::index_sequence<Is...>) {
using prop_getter_t = typename GRAPH_INTERFACE::template multi_prop_getter_t<
typename SELECTOR::prop_t...>;
std::array<prop_getter_t, num_labels> prop_getter_array{
get_prop_getter_from_selectors(graph, labels[Is], selectors)...};
return prop_getter_array;
}
// Get prop getters from Selector, with label vector.
template <typename GRAPH_INTERFACE, typename LabelT, typename... SELECTOR,
size_t... Is>
static auto get_prop_getters_from_selectors_impl_label_vec(
const GRAPH_INTERFACE& graph, const std::vector<LabelT>& labels,
std::tuple<SELECTOR...> selectors) {
using prop_getter_t = typename GRAPH_INTERFACE::template multi_prop_getter_t<
typename SELECTOR::prop_t...>;
std::vector<prop_getter_t> prop_getter_array;
for (size_t i = 0; i < labels.size(); ++i) {
prop_getter_array.emplace_back(
get_prop_getter_from_selectors(graph, labels[i], selectors));
};
return prop_getter_array;
}
template <typename GRAPH_INTERFACE, typename LabelT, size_t num_labels,
typename... SELECTOR>
static auto get_prop_getters_from_selectors(
const GRAPH_INTERFACE& graph, const std::array<LabelT, num_labels>& labels,
std::tuple<SELECTOR...> named_property) {
return get_prop_getters_from_selectors_impl(
graph, labels, named_property, std::make_index_sequence<num_labels>{});
}
template <typename GRAPH_INTERFACE, typename LabelT, typename... SELECTOR>
static auto get_prop_getters_from_selectors(
const GRAPH_INTERFACE& graph, const std::vector<LabelT>& labels,
std::tuple<SELECTOR...> named_property) {
return get_prop_getters_from_selectors_impl_label_vec(graph, labels,
named_property);
}
///////////////////////// prop getter for vertex set
//////////////////////////////
template <int tag_id, typename T>
class VertexInnerIdGetter {
public:
using prop_element_t = T;
VertexInnerIdGetter() {}
T get_view(const T& ele) const { return ele; }
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& ind_ele) const {
return get_view(gs::get_from_tuple<tag_id>(ind_ele));
}
};
template <int tag_id, typename T>
class CollectionInnerIdGetter {
public:
using prop_element_t = T;
CollectionInnerIdGetter() {}
T get_view(const T& ele) const { return ele; }
T get_view(const std::tuple<T>& ele) const { return std::get<0>(ele); }
T get_view(const std::tuple<size_t, T>& ele) const {
return std::get<1>(ele);
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& ind_ele) const {
return get_view(std::get<1>(gs::get_from_tuple<tag_id>(ind_ele)));
}
};
template <int tag_id, typename VID_T>
class VertexGlobalIdGetter {
public:
using prop_element_t = GlobalId;
VertexGlobalIdGetter(const std::vector<VID_T>& vids,
std::vector<LabelKey>&& label_vec)
: vids_(vids), label_vec_(std::move(label_vec)) {}
GlobalId get_view(const std::tuple<size_t, int32_t, VID_T>& ele) const {
return GlobalId(label_vec_[std::get<0>(ele)].label_id,
vids_[std::get<0>(ele)]);
}
// two label set
GlobalId get_view(const std::tuple<size_t, VID_T>& ele) const {
return GlobalId(label_vec_[std::get<0>(ele)].label_id,
vids_[std::get<0>(ele)]);
}
// general vertex set
template <typename... T>
GlobalId get_view(
const std::tuple<size_t, size_t, VID_T, std::tuple<T...>>& ele) const {
return GlobalId(std::get<1>(ele), std::get<2>(ele));
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
return gs::get_from_tuple<tag_id>(all_ele);
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(
const ALL_IND_ELE_T& all_ind_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ind_ele));
}
private:
const std::vector<VID_T>& vids_;
std::vector<LabelKey> label_vec_;
};
template <int tag_id>
class VertexLabelGetter {
public:
using prop_element_t = LabelKey;
VertexLabelGetter(const std::vector<LabelKey>&& label_keys)
: label_keys(std::move(label_keys)) {}
template <typename IND_ELE>
LabelKey get_view(const IND_ELE& ele) const {
auto index_ = std::get<0>(ele);
if (index_ >= label_keys.size()) {
LOG(FATAL) << "index out of range";
}
return label_keys[index_];
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
return gs::get_from_tuple<tag_id>(all_ele).label();
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& ind_ele) const {
return get_view(gs::get_from_tuple<tag_id>(ind_ele));
}
private:
std::vector<LabelKey> label_keys;
};
template <int tag_id>
class EdgeLabelGetter {
public:
using prop_element_t = LabelKey;
EdgeLabelGetter(const std::vector<LabelKey>&& label_keys)
: label_keys(std::move(label_keys)) {}
template <typename IND_ELE>
LabelKey get_view(const IND_ELE& ele) const {
auto index_ = std::get<0>(ele);
if (index_ >= label_keys.size()) {
LOG(FATAL) << "index out of range";
}
return label_keys[index_];
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
private:
std::vector<LabelKey> label_keys;
};
template <int tag_id, typename VID_T, typename... DATA_T>
class InnerIdDataGetter {
public:
using prop_element_t = std::tuple<VID_T, std::tuple<DATA_T...>>;
InnerIdDataGetter(const std::vector<VID_T>& vids,
const std::vector<std::tuple<DATA_T...>>& data)
: vids_(vids), data_(data) {}
std::tuple<VID_T, std::tuple<DATA_T...>> get_view(
const std::tuple<size_t, VID_T>& ele) const {
auto vid = std::get<1>(ele);
auto idx = std::get<0>(ele);
CHECK(vid == vids_[idx]);
return std::make_tuple(vid, std::get<0>(data_[idx]));
}
template <typename TUPLE_T>
auto get_from_all_element(const TUPLE_T& tuple) const {
auto ind_ele = gs::get_from_tuple<tag_id>(tuple);
return ind_ele;
}
private:
const std::vector<VID_T>& vids_;
const std::vector<std::tuple<DATA_T...>>& data_;
};
template <int tag_id, typename PROP_GETTER_T, typename IND_ELE_T>
class GeneralVertexSetPropGetter {
public:
using prop_element_t = typename PROP_GETTER_T::value_type;
using ELE_TUPLE_T = GlobalId;
GeneralVertexSetPropGetter(std::vector<PROP_GETTER_T>&& getters,
const std::vector<grape::Bitset>& bitset)
: getters_(std::move(getters)), bitset_(bitset) {}
inline auto get_view(const IND_ELE_T& ind_ele) const {
auto vid = std::get<2>(ind_ele);
auto label_ind = std::get<1>(ind_ele);
CHECK(std::get<0>(ind_ele) < bitset_[label_ind].cardinality());
CHECK(bitset_[label_ind].get_bit(std::get<0>(ind_ele)));
return getters_[label_ind].get_view(vid);
}
inline auto get_view(const ELE_TUPLE_T& ele) const {
CHECK(ele.label_id() < bitset_.size());
return getters_[ele.label_id()].get_view(ele.vid());
}
inline auto get_view() const { return get_view(ind_ele_); }
template <typename TUPLE_T>
auto get_from_all_element(const TUPLE_T& tuple) const {
auto ind_ele = gs::get_from_tuple<tag_id>(tuple);
return get_view(ind_ele);
}
template <typename ALL_IND_TUPLE_T>
auto get_from_all_index_element(const ALL_IND_TUPLE_T& tuple) const {
auto ind_ele = gs::get_from_tuple<tag_id>(tuple);
return get_view(ind_ele);
}
private:
IND_ELE_T ind_ele_;
std::vector<PROP_GETTER_T> getters_;
const std::vector<grape::Bitset>& bitset_;
};
// For EdgeSetInnerIdGetter, we return a wrapped EdgeObject.
template <int tag_id, typename VID_T, typename EDATA_T>
class EdgeSetInnerIdGetter {
public:
using prop_element_t = Edge<VID_T, grape::EmptyType>;
EdgeSetInnerIdGetter() {}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
auto& tuple = gs::get_from_tuple<tag_id>(all_ele);
using cur_tuple_t =
std::remove_const_t<std::remove_reference_t<decltype(tuple)>>;
if constexpr ((std::tuple_size_v<cur_tuple_t>) > 2) {
auto src_vid = std::get<0>(tuple);
auto dst_vid = std::get<1>(tuple);
return Edge<VID_T, grape::EmptyType>(src_vid, dst_vid);
} else if constexpr (std::tuple_size_v<cur_tuple_t> == 2) {
auto& actual_tuple = std::get<1>(tuple);
auto src_vid = std::get<0>(actual_tuple);
auto dst_vid = std::get<1>(actual_tuple);
return Edge<VID_T, grape::EmptyType>(src_vid, dst_vid);
} else {
LOG(FATAL) << "tuple size error";
}
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& ind_ele) const {
return get_from_all_element(ind_ele);
}
};
template <int tag_id, typename T>
class CollectionPropGetter {
public:
using prop_element_t = T;
CollectionPropGetter() {}
inline auto get_view(const std::tuple<size_t, T>& ele) const {
return std::get<1>(ele);
}
inline auto get_view(const T& ele) const { return ele; }
inline auto get_view() const { return std::get<1>(ind_ele_); }
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& all_ele) {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = ind_ele;
}
private:
std::tuple<size_t, T> ind_ele_;
};
// Specialize for LabelKey
template <int tag_id>
class CollectionPropGetter<tag_id, LabelKey> {
public:
using prop_element_t = LabelKey;
CollectionPropGetter() {}
inline auto get_view(const std::tuple<size_t, LabelKey>& ele) const {
return std::get<1>(ele).label_id;
}
inline auto get_view() const { return std::get<1>(ind_ele_); }
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = ind_ele;
}
private:
std::tuple<size_t, LabelKey> ind_ele_;
};
// specialize for collection with only one column
template <int tag_id, typename T>
class CollectionPropGetter<tag_id, std::tuple<T>> {
public:
using prop_element_t = T;
CollectionPropGetter() {}
inline T get_view(const std::tuple<size_t, T>& ele) const {
return std::get<1>(ele);
}
inline T get_view() const { return std::get<1>(ind_ele_); }
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
return gs::get_from_tuple<tag_id>(all_ele);
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& ind_ele) const {
return get_view(gs::get_from_tuple<tag_id>(ind_ele));
}
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = ind_ele;
}
private:
std::tuple<size_t, T> ind_ele_;
};
template <int tag_id, typename index_ele_tuple_t>
class FlatEdgeSetPropGetter {
public:
using prop_element_t = typename std::tuple_element_t<
0, typename std::tuple_element_t<
2, typename std::tuple_element_t<1, index_ele_tuple_t>>>;
FlatEdgeSetPropGetter() {}
inline auto get_view(const index_ele_tuple_t& ind_ele) const {
return std::get<0>(std::get<2>(std::get<1>(ind_ele)));
}
inline auto get_view()
const { // const std::tuple<size_t, int32_t, VID_T>& ind_ele
return std::get<0>(std::get<2>(std::get<1>(ind_ele_)));
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
auto& my_ele = gs::get_from_tuple<tag_id>(all_ele);
return get_view(my_ele);
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& ind_ele) const {
return get_view(gs::get_from_tuple<tag_id>(ind_ele));
}
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = gs::get_from_tuple<tag_id>(ind_ele);
}
private:
index_ele_tuple_t ind_ele_;
};
template <int tag_id, typename PropT>
class UnTypedEdgeSetPropGetter {
public:
using index_ele_tuple_t = std::tuple<size_t, vid_t, vid_t, Any>;
using prop_element_t = PropT;
UnTypedEdgeSetPropGetter() {}
inline auto get_view(const index_ele_tuple_t& ind_ele) const {
PropT prop;
ConvertAny<PropT>::to(std::get<3>(ind_ele), prop);
return prop;
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
auto& my_ele = gs::get_from_tuple<tag_id>(all_ele);
return get_view(my_ele);
}
};
template <int tag_id, typename index_ele_tuple_t>
class GeneralEdgeSetPropGetter {
public:
using adj_iterator_t = typename std::tuple_element_t<2, index_ele_tuple_t>;
using prop_element_t = typename adj_iterator_t::edge_property_t;
GeneralEdgeSetPropGetter() {}
inline auto get_view(const index_ele_tuple_t& ind_ele) const {
return std::get<0>(std::get<2>(ind_ele).properties());
}
inline auto get_view()
const { // const std::tuple<size_t, int32_t, VID_T>& ind_ele
return std::get<0>(std::get<2>(ind_ele_).properties());
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
auto& my_ele = gs::get_from_tuple<tag_id>(all_ele);
return get_view(my_ele);
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = gs::get_from_tuple<tag_id>(ind_ele);
}
private:
index_ele_tuple_t ind_ele_;
};
template <int tag_id, typename PROP_GETTER_T, typename IND_ELE_T>
class TwoLabelVertexSetImplPropGetter {
public:
using prop_element_t = typename PROP_GETTER_T::value_type;
TwoLabelVertexSetImplPropGetter(std::array<PROP_GETTER_T, 2>&& getters)
: getters_(std::move(getters)) {}
inline auto get_view(const IND_ELE_T& ind_ele) const {
return getters_[std::get<1>(ind_ele)].get_view(std::get<2>(ind_ele));
}
inline auto get_view(const std::pair<int32_t, vid_t>& ind_ele) const {
return getters_[ind_ele.first].get_view(ind_ele.second);
}
inline auto get_view()
const { // const std::tuple<size_t, int32_t, VID_T>& ind_ele
return getters_[std::get<1>(ind_ele_)].get_view(std::get<2>(ind_ele_));
}
template <typename ALL_INDEX_ELE_T>
inline auto get_from_all_element(const ALL_INDEX_ELE_T& all_ele) const {
auto& my_ele = gs::get_from_tuple<tag_id>(all_ele);
return get_view(my_ele);
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ELE_T>
inline auto get_from_element(const ELE_T& ele) const {
return getters_[std::get<0>(ele)].get_view(std::get<1>(ele));
}
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = gs::get_from_tuple<tag_id>(ind_ele);
}
private:
IND_ELE_T ind_ele_;
std::array<PROP_GETTER_T, 2> getters_;
};
template <int tag_id, typename PROP_GETTER_T, typename IND_ELE_T>
class RowVertexSetPropGetter {
public:
using prop_element_t = typename PROP_GETTER_T::value_type;
RowVertexSetPropGetter(PROP_GETTER_T&& getter) : getter_(std::move(getter)) {}
template <typename VID_T>
inline auto get_view(const std::tuple<size_t, VID_T>& ind_ele) const {
return getter_.get_view(std::get<1>(ind_ele));
}
template <typename VID_T>
inline auto get_view(const VID_T& vid) const {
return getter_.get_view(vid);
}
inline auto get_view(const GlobalId& global_id) const {
return getter_.get_view(global_id.vid());
}
inline auto get_view() const {
return getter_.get_view(std::get<1>(ind_ele_));
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
auto& my_ele = gs::get_from_tuple<tag_id>(all_ele);
return get_view(my_ele);
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& ind_ele) const {
return get_view(gs::get_from_tuple<tag_id>(ind_ele));
}
// get from ele
template <typename ELE_T>
inline auto get_from_element(const ELE_T& ele) const {
return getter_.get_view(ele);
}
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = gs::get_from_tuple<tag_id>(ind_ele);
}
private:
IND_ELE_T ind_ele_;
PROP_GETTER_T getter_;
};
template <int tag_id, typename PROP_GETTER_T, typename IND_ELE_T>
class KeyedRowVertexSetPropGetter {
public:
using prop_element_t = typename PROP_GETTER_T::value_type;
KeyedRowVertexSetPropGetter(PROP_GETTER_T&& getter)
: getter_(std::move(getter)) {}
template <typename VID_T>
inline auto get_view(const std::tuple<size_t, VID_T>& ind_ele) const {
return getter_.get_view(std::get<1>(ind_ele));
}
inline auto get_view(const GlobalId& global_id) const {
return getter_.get_view(global_id.vid());
}
inline auto get_view() const {
return getter_.get_view(std::get<1>(ind_ele_));
}
template <typename ALL_ELE_T>
inline auto get_from_all_element(const ALL_ELE_T& all_ele) const {
auto& my_ele = gs::get_from_tuple<tag_id>(all_ele);
return get_view(my_ele);
}
template <typename ALL_IND_ELE_T>
inline auto get_from_all_index_element(const ALL_IND_ELE_T& all_ele) const {
return get_view(gs::get_from_tuple<tag_id>(all_ele));
}
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = gs::get_from_tuple<tag_id>(ind_ele);
}
private:
IND_ELE_T ind_ele_;
PROP_GETTER_T getter_;
};
template <int tag_id, typename IND_ELE_T>
class DistGetter {
public:
using prop_element_t = Dist;
DistGetter(std::vector<Dist>&& dist) : dist_(std::move(dist)) {}
template <typename VID_T>
inline auto get_view(const std::tuple<size_t, VID_T>& ind_ele) const {
return dist_[std::get<0>(ind_ele)];
}
inline auto get_view() const { return dist_[std::get<0>(ind_ele_)]; }
template <typename ALL_IND_ELE_T>
inline void set_ind_ele(const ALL_IND_ELE_T& ind_ele) {
ind_ele_ = gs::get_from_tuple<tag_id>(ind_ele);
}
private:
std::vector<Dist> dist_;
IND_ELE_T ind_ele_;
};
///////////////////////Creating property getter/////////////////////////
template <int tag_id, size_t Is = 0, typename LabelT, typename VID_T,
typename... T>
static auto get_dist_prop_getter(
const RowVertexSetImpl<LabelT, VID_T, T...>& set,
const std::array<std::string, sizeof...(T)>& prop_names) {
if (prop_names[Is] == "dist" || prop_names[Is] == "Dist") {
std::vector<Dist> dists;
auto& data_vec = set.GetDataVec();
dists.reserve(set.Size());
for (size_t i = 0; i < data_vec.size(); ++i) {
dists.emplace_back(Dist(std::get<Is>(data_vec[i])));
}
return DistGetter<tag_id, typename RowVertexSetImpl<
LabelT, VID_T, T...>::index_ele_tuple_t>(
std::move(dists));
}
if constexpr (Is + 1 >= sizeof...(T)) {
LOG(WARNING) << "Property dist not found, using default 0";
std::vector<Dist> dists;
auto set_size = set.Size();
dists.reserve(set_size);
for (size_t i = 0; i < set_size; ++i) {
dists.emplace_back(0);
}
return DistGetter<tag_id, typename RowVertexSetImpl<
LabelT, VID_T, T...>::index_ele_tuple_t>(
std::move(dists));
} else {
return get_dist_prop_getter<tag_id, Is + 1>(set, prop_names);
}
}
// getting dist prop for keyed row vertex set
template <int tag_id, size_t Is = 0, typename LabelT, typename KEY_T,
typename VID_T, typename... T>
static auto get_dist_prop_getter(
const KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T, T...>& set,
const std::array<std::string, sizeof...(T)>& prop_names) {
if (prop_names[Is] == "dist" || prop_names[Is] == "Dist") {
std::vector<Dist> dists;
auto& data_vec = set.GetDataVec();
dists.reserve(set.Size());
for (size_t i = 0; i < data_vec.size(); ++i) {
dists.emplace_back(Dist(std::get<Is>(data_vec[i])));
}
return DistGetter<tag_id,
typename KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T,
T...>::index_ele_tuple_t>(
std::move(dists));
}
if constexpr (Is + 1 >= sizeof...(T)) {
LOG(WARNING) << "Property dist not found, using default 0";
std::vector<Dist> dists;
auto set_size = set.Size();
dists.reserve(set_size);
for (size_t i = 0; i < set_size; ++i) {
dists.emplace_back(0);
}
return DistGetter<tag_id,
typename KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T,
T...>::index_ele_tuple_t>(
std::move(dists));
} else {
return get_dist_prop_getter<tag_id, Is + 1>(set, prop_names);
}
}
///////////////////// Get LabelKey Property for VertexSet
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE,
typename NODE_T,
typename std::enable_if<(std::is_same_v<prop_t, LabelKey> &&
NODE_T::is_vertex_set)>::type* = nullptr>
static auto create_prop_getter_impl(const NODE_T& set,
const GRAPH_INTERFACE& graph,
const std::string& prop_name) {
auto label_vec = set.GetLabelVec();
return VertexLabelGetter<tag_id>(std::move(label_vec));
}
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE,
typename NODE_T,
typename std::enable_if<(std::is_same_v<prop_t, LabelKey> &&
NODE_T::is_edge_set)>::type* = nullptr>
static auto create_prop_getter_impl(const NODE_T& set,
const GRAPH_INTERFACE& graph,
const std::string& prop_name) {
auto label_vec = set.GetLabelVec();
return EdgeLabelGetter<tag_id>(std::move(label_vec));
}
// get for common properties for two_vertex_set
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE,
typename LabelT, typename VID_T, typename... T,
typename std::enable_if<(!std::is_same_v<prop_t, Dist> &&
!std::is_same_v<prop_t, LabelKey>)>::type* =
nullptr>
static auto create_prop_getter_impl(
const RowVertexSetImpl<LabelT, VID_T, T...>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
using prop_getter_t =
typename GRAPH_INTERFACE::template single_prop_getter_t<prop_t>;
// const std::array<std::string, 2>& labels = set.GetLabels();
auto label = set.GetLabel();
VLOG(10) << "getting getter for " << prop_name << " for label "
<< gs::to_string(label);
auto getter = graph.template GetSinglePropGetter<prop_t>(label, prop_name);
return RowVertexSetPropGetter<
tag_id, prop_getter_t,
typename RowVertexSetImpl<LabelT, VID_T, T...>::index_ele_tuple_t>(
std::move(getter));
}
// get for dist property for row_vertex_set
template <
int tag_id, typename prop_t, typename GRAPH_INTERFACE, typename LabelT,
typename VID_T, typename... T,
typename std::enable_if<std::is_same_v<prop_t, Dist>>::type* = nullptr>
static auto create_prop_getter_impl(
const RowVertexSetImpl<LabelT, VID_T, T...>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
VLOG(10) << "Getting dist prop getter";
CHECK(prop_name == "dist" || prop_name == "Dist");
return get_dist_prop_getter<tag_id>(set, set.GetPropNames());
}
// get dist property for keyed vertex set
template <
int tag_id, typename prop_t, typename GRAPH_INTERFACE, typename LabelT,
typename KEY_T, typename VID_T, typename... T,
typename std::enable_if<std::is_same_v<prop_t, Dist>>::type* = nullptr>
static auto create_prop_getter_impl(
const KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T, T...>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
VLOG(10) << "Getting dist prop getter";
CHECK(prop_name == "dist" || prop_name == "Dist");
return get_dist_prop_getter<tag_id>(set, set.GetPropNames());
}
// get for common properties for two_label_vertex_set
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE, typename VID_T,
typename LabelT, typename... T,
typename std::enable_if<!(std::is_same_v<prop_t, LabelKey>)>::type* =
nullptr>
static auto create_prop_getter_impl(
const TwoLabelVertexSetImpl<VID_T, LabelT, T...>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
using prop_getter_t =
typename GRAPH_INTERFACE::template single_prop_getter_t<prop_t>;
auto& labels = set.GetLabels();
std::array<std::string, 1> names{prop_name};
VLOG(10) << "Getting prop labels for " << prop_name << " for labels "
<< std::to_string(labels[0]) << ", " << std::to_string(labels[1]);
std::array<prop_getter_t, 2> prop_getter{
graph.template GetSinglePropGetter<prop_t>(labels[0], prop_name),
graph.template GetSinglePropGetter<prop_t>(labels[1], prop_name)};
return TwoLabelVertexSetImplPropGetter<
tag_id, prop_getter_t,
typename TwoLabelVertexSetImpl<VID_T, LabelT, T...>::index_ele_tuple_t>(
std::move(prop_getter));
}
// get for common properties for keyed_row_vertex_set
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE,
typename LabelT, typename KEY_T, typename VID_T, typename... T,
typename std::enable_if<(!std::is_same_v<prop_t, Dist> &&
!std::is_same_v<prop_t, LabelKey>)>::type* =
nullptr>
static auto create_prop_getter_impl(
const KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T, T...>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
using prop_getter_t =
typename GRAPH_INTERFACE::template single_prop_getter_t<prop_t>;
// const std::array<std::string, 2>& labels = set.GetLabels();
auto label = set.GetLabel();
auto getter = graph.template GetSinglePropGetter<prop_t>(label, prop_name);
return KeyedRowVertexSetPropGetter<
tag_id, prop_getter_t,
typename KeyedRowVertexSetImpl<LabelT, KEY_T, VID_T,
T...>::index_ele_tuple_t>(
std::move(getter));
}
// get for common properties for keyed_row_vertex_set
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE,
typename LabelT, typename VID_T, typename... SET_T,
typename std::enable_if<!(std::is_same_v<prop_t, LabelKey>)>::type* =
nullptr>
static auto create_prop_getter_impl(
const GeneralVertexSet<VID_T, LabelT, SET_T...>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
using prop_getter_t =
typename GRAPH_INTERFACE::template single_prop_getter_t<prop_t>;
// const std::array<std::string, 2>& labels = set.GetLabels();
auto labels = set.GetLabels();
std::vector<prop_getter_t> prop_getters;
for (size_t i = 0; i < labels.size(); ++i) {
prop_getters.emplace_back(
graph.template GetSinglePropGetter<prop_t>(labels[i], prop_name));
}
return GeneralVertexSetPropGetter<
tag_id, prop_getter_t,
typename GeneralVertexSet<VID_T, LabelT, SET_T...>::index_ele_tuple_t>(
std::move(prop_getters), set.GetBitsets());
}
// get for common properties for FlatEdgeSet
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE, typename VID_T,
typename LabelT, typename EDATA_T,
typename std::enable_if<!(std::is_same_v<prop_t, LabelKey>)>::type* =
nullptr>
static auto create_prop_getter_impl(
const FlatEdgeSet<VID_T, LabelT, EDATA_T>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
return FlatEdgeSetPropGetter<
tag_id,
typename FlatEdgeSet<VID_T, LabelT, EDATA_T>::index_ele_tuple_t>();
}
// get for common properties for UntypedEdgeSet
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE, typename VID_T,
typename LabelT, typename SUB_GRAPH_T,
typename std::enable_if<!(std::is_same_v<prop_t, LabelKey>)>::type* =
nullptr>
static auto create_prop_getter_impl(
const UnTypedEdgeSet<VID_T, LabelT, SUB_GRAPH_T>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
return UnTypedEdgeSetPropGetter<tag_id, prop_t>();
}
// get for common properties for Single label edge set.
template <int tag_id, typename prop_t, typename GRAPH_INTERFACE, typename VID_T,
typename LabelT, typename EDATA_T,
typename std::enable_if<!(std::is_same_v<prop_t, LabelKey>)>::type* =
nullptr>
static auto create_prop_getter_impl(
const SingleLabelEdgeSet<VID_T, LabelT, EDATA_T>& set,
const GRAPH_INTERFACE& graph, const std::string& prop_name) {
// single label edge set is a special kind of flat edge set.
return FlatEdgeSetPropGetter<
tag_id,
typename SingleLabelEdgeSet<VID_T, LabelT, EDATA_T>::index_ele_tuple_t>();
}
// get for common properties for GeneralEdgeSet
template <int tag_id, typename prop_t, size_t N, typename GI, typename VID_T,
typename LabelT, typename... EDATA_T,
typename std::enable_if<!(std::is_same_v<prop_t, LabelKey>)>::type* =
nullptr>
static auto create_prop_getter_impl(
const GeneralEdgeSet<N, GI, VID_T, LabelT, EDATA_T...>& set,
const GI& graph, const std::string& prop_name) {
return GeneralEdgeSetPropGetter<
tag_id, typename GeneralEdgeSet<N, GI, VID_T, LabelT,
EDATA_T...>::index_ele_tuple_t>();
}
// get for common properties for collection
template <int tag_id, typename prop_t, typename GI, typename T>
static auto create_prop_getter_impl(const Collection<T>& set, const GI& graph,
const std::string& prop_name) {
CHECK(prop_name == "None" || prop_name == "none" || prop_name == "");
return CollectionPropGetter<tag_id, T>();
}
// create inner id getter for row vertex set with props
template <typename GRAPH_INTERFACE, typename LabelT, typename... SET_Ts,
int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph,
const RowVertexSetImpl<LabelT, typename GRAPH_INTERFACE::vertex_id_t,
SET_Ts...>& set,
const InnerIdProperty<tag_id>& inner_id_prop) {
return InnerIdDataGetter<tag_id, typename GRAPH_INTERFACE::vertex_id_t,
SET_Ts...>(set.GetVertices(), set.GetDataVec());
}
// create inner id getter for keyed row vertex set without props
template <typename GRAPH_INTERFACE, typename LabelT, int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph,
const RowVertexSetImpl<LabelT, typename GRAPH_INTERFACE::vertex_id_t,
grape::EmptyType>& set,
const InnerIdProperty<tag_id>& inner_id_prop) {
return VertexInnerIdGetter<tag_id, GlobalId>();
}
// create inner_id getter for two label vertex set
template <typename GRAPH_INTERFACE, typename LabelT, typename... SET_Ts,
int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph,
const TwoLabelVertexSetImpl<typename GRAPH_INTERFACE::vertex_id_t, LabelT,
SET_Ts...>& set,
const InnerIdProperty<tag_id>& inner_id_prop) {
return VertexInnerIdGetter<tag_id, GlobalId>(set.GetVertices());
}
// create inner_id getter for two label vertex set
template <typename GRAPH_INTERFACE, typename LabelT, typename... SET_Ts,
int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph,
const GeneralVertexSet<typename GRAPH_INTERFACE::vertex_id_t, LabelT,
SET_Ts...>& set,
const InnerIdProperty<tag_id>& inner_id_prop) {
return VertexInnerIdGetter<tag_id, GlobalId>(set.GetVertices());
}
// create inner id getter for collection.
template <typename GRAPH_INTERFACE, typename COL_T, int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph, const Collection<COL_T>& set,
const InnerIdProperty<tag_id>& inner_id_prop) {
return CollectionInnerIdGetter<tag_id, COL_T>();
}
// create innerId getter for flat edge set.
template <typename GRAPH_INTERFACE, typename VID_T, typename LabelT,
typename EDATA_T, int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph,
const FlatEdgeSet<VID_T, LabelT, EDATA_T>& set,
const InnerIdProperty<tag_id>& inner_id_prop) {
return EdgeSetInnerIdGetter<tag_id, VID_T, EDATA_T>();
}
// create inner id getter for single_label_edge_set.
template <typename GRAPH_INTERFACE, typename VID_T, typename LabelT,
typename EDATA_T, int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph,
const SingleLabelEdgeSet<VID_T, LabelT, EDATA_T>& set,
const InnerIdProperty<tag_id>& inner_id_prop) {
return EdgeSetInnerIdGetter<tag_id, VID_T, EDATA_T>();
}
// create GlobalId getter for vertex_set
template <typename GRAPH_INTERFACE, typename VERTEX_SET_T, int tag_id,
typename std::enable_if<VERTEX_SET_T::is_vertex_set>::type* = nullptr>
static auto create_global_id_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph, const VERTEX_SET_T& set,
const GlobalIdProperty<tag_id>& global_id_prop) {
return VertexGlobalIdGetter<tag_id, typename GRAPH_INTERFACE::vertex_id_t>(
set.GetVertices(), set.GetLabelVec());
}
// create global id getter for collection
template <typename GRAPH_INTERFACE, typename T, int tag_id>
static auto create_global_id_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph, const Collection<T>& set,
const GlobalIdProperty<tag_id>& global_id_prop) {
return CollectionInnerIdGetter<tag_id, T>();
}
// create global id getter for EdgeSet
template <typename GRAPH_INTERFACE, typename EDGE_SET_T, int tag_id,
typename std::enable_if<EDGE_SET_T::is_edge_set>::type* = nullptr>
static auto create_global_id_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph, const EDGE_SET_T& set,
const GlobalIdProperty<tag_id>& global_id_prop) {
return EdgeSetInnerIdGetter<tag_id, typename GRAPH_INTERFACE::vertex_id_t,
typename EDGE_SET_T::edata_t>();
}
// get prop for inner id for idKey
template <typename GRAPH_INTERFACE, typename CTX_HEAD_T, int cur_alias,
int base_tag, typename... CTX_PREV, int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph,
Context<CTX_HEAD_T, cur_alias, base_tag, CTX_PREV...>& ctx,
const InnerIdProperty<tag_id>& inner_id_prop) {
auto& set = ctx.template GetNode<tag_id>();
return create_prop_getter_from_prop_desc(graph, set, inner_id_prop);
}
// get prop for global id for idKey
template <typename GRAPH_INTERFACE, typename CTX_HEAD_T, int cur_alias,
int base_tag, typename... CTX_PREV, int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph,
Context<CTX_HEAD_T, cur_alias, base_tag, CTX_PREV...>& ctx,
const GlobalIdProperty<tag_id>& global_id_property) {
auto& set = ctx.template GetNode<tag_id>();
return create_global_id_prop_getter_from_prop_desc(graph, set,
global_id_property);
}
// get prop for common property.
// return a single prop getter
template <typename GRAPH_INTERFACE, typename CTX_T, typename T, int tag_id>
static auto create_prop_getter_from_prop_desc(
const GRAPH_INTERFACE& graph, CTX_T& ctx,
const NamedProperty<T, tag_id>& named_property) {
auto& set = ctx.template GetNode<tag_id>();
return create_prop_getter_impl<tag_id, T>(set, graph, named_property.name);
}
template <typename GI, typename CTX_T, typename... PROP_DESC, size_t... Is>
static auto create_prop_getters_from_prop_desc(
const GI& graph, CTX_T& ctx, const std::tuple<PROP_DESC...>& prop_desc,
std::index_sequence<Is...>) {
return std::make_tuple(create_prop_getter_from_prop_desc(
graph, ctx, std::get<Is>(prop_desc))...);
}
template <typename GI, typename CTX_T, typename... PROP_DESC>
static auto create_prop_getters_from_prop_desc(
const GI& graph, CTX_T& ctx, const std::tuple<PROP_DESC...>& prop_desc) {
return create_prop_getters_from_prop_desc(
graph, ctx, prop_desc, std::make_index_sequence<sizeof...(PROP_DESC)>());
}
template <int col_id>
auto create_prop_desc_from_selector(
const PropertySelector<grape::EmptyType>& selector) {
return InnerIdProperty<col_id>();
}
// For getting edge_set's edge
template <int col_id, typename VID_T>
auto create_prop_desc_from_selector(
const PropertySelector<const DefaultEdge<VID_T>&>& selector) {
return InnerIdProperty<col_id>();
}
template <int col_id>
auto create_prop_desc_from_selector(
const PropertySelector<GlobalId>& selector) {
return GlobalIdProperty<col_id>();
}
template <int col_id, typename T>
auto create_prop_desc_from_selector(const PropertySelector<T>& selector) {
return NamedProperty<T, col_id>(selector.prop_name_);
}
template <int... in_col_id, typename... SELECTOR, size_t... Ind>
auto create_prop_descs_from_selectors(std::integer_sequence<int, in_col_id...>,
const std::tuple<SELECTOR...>& selectors,
std::index_sequence<Ind...>) {
return std::make_tuple(
create_prop_desc_from_selector<in_col_id>(std::get<Ind>(selectors))...);
}
template <AggFunc agg_func, typename PropT, int tag_id>
auto create_prop_desc_from_aggregate_prop(
const AggregateProp<agg_func, std::tuple<PropT>,
std::integer_sequence<int32_t, tag_id>>& agg_prop) {
return create_prop_desc_from_selector<tag_id>(
std::get<0>(agg_prop.selectors_));
}
template <int... in_col_id, typename... SELECTOR>
auto create_prop_descs_from_selectors(
const std::tuple<SELECTOR...>& selectors) {
return create_prop_descs_from_selectors(
std::integer_sequence<int, in_col_id...>(), selectors,
std::make_index_sequence<sizeof...(SELECTOR)>());
}
template <typename... GROUP_KEY, size_t... Is>
static auto create_prop_descs_from_group_keys_impl(
const std::tuple<GROUP_KEY...>& group_keys, std::index_sequence<Is...>) {
auto tuple = std::make_tuple(std::get<Is>(group_keys).selector_...);
return create_prop_descs_from_selectors<GROUP_KEY::col_id...>(tuple);
}
template <typename... GROUP_KEY>
static auto create_prop_descs_from_group_keys(
const std::tuple<GROUP_KEY...>& group_keys) {
return create_prop_descs_from_group_keys_impl(
group_keys, std::make_index_sequence<sizeof...(GROUP_KEY)>());
}
template <typename... PropTGetter, typename... IndexEle, size_t... Is>
auto get_prop_from_index_ele_with_prop_getter(
const std::tuple<PropTGetter...>& prop_getters,
const std::tuple<IndexEle...>& index_ele, std::index_sequence<Is...>) {
return std::make_tuple(
std::get<Is>(prop_getters).get_from_all_index_element(index_ele)...);
}
} // namespace gs
#endif // ENGINES_HQPS_ENGINE_OPERATOR_PROP_UTILS_H_