in flex/engines/graph_db/runtime/common/operators/retrieve/edge_expand.cc [212:530]
bl::result<Context> EdgeExpand::expand_edge_without_predicate(
const GraphReadInterface& graph, Context&& ctx,
const EdgeExpandParams& params, OprTimer& timer) {
if (params.is_optional) {
TimerUnit tx;
tx.start();
auto ret = expand_edge_without_predicate_optional_impl(
graph, std::move(ctx), params);
timer.record_routine("#### expand_edge_without_predicate_optional", tx);
return ret;
}
std::vector<size_t> shuffle_offset;
if (params.labels.size() == 1) {
if (params.dir == Direction::kIn) {
auto& input_vertex_list =
*std::dynamic_pointer_cast<IVertexColumn>(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 = graph.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];
}
auto builder =
SDSLEdgeColumnBuilder::builder(Direction::kIn, params.labels[0], pt);
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 = graph.GetInEdgeIterator(
label, v, output_vertex_label, edge_label);
while (ie_iter.IsValid()) {
auto nbr = ie_iter.GetNeighbor();
assert(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(nullptr),
shuffle_offset);
return ctx;
} else if (params.dir == Direction::kOut) {
auto& input_vertex_list =
*std::dynamic_pointer_cast<IVertexColumn>(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 = graph.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;
}
auto builder =
SDSLEdgeColumnBuilder::builder(Direction::kOut, params.labels[0], pt);
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 = graph.GetOutEdgeIterator(
label, v, output_vertex_label, edge_label);
while (oe_iter.IsValid()) {
auto nbr = oe_iter.GetNeighbor();
assert(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(nullptr),
shuffle_offset);
return ctx;
} else {
auto& input_vertex_list =
*std::dynamic_pointer_cast<IVertexColumn>(ctx.get(params.v_tag));
auto props = graph.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];
}
auto builder = 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 =
graph.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 =
graph.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(nullptr),
shuffle_offset);
return ctx;
}
} else {
auto column =
std::dynamic_pointer_cast<IVertexColumn>(ctx.get(params.v_tag));
auto label_set = column->get_labels_set();
auto labels =
get_expand_label_set(graph, label_set, params.labels, params.dir);
std::vector<std::pair<LabelTriplet, PropertyType>> label_props;
std::vector<std::vector<PropertyType>> props_vec;
std::vector<std::vector<LabelTriplet>> in_labels_map(
graph.schema().vertex_label_num()),
out_labels_map(graph.schema().vertex_label_num());
for (const auto& triplet : labels) {
auto& props = graph.schema().get_edge_properties(
triplet.src_label, triplet.dst_label, triplet.edge_label);
in_labels_map[triplet.dst_label].emplace_back(triplet);
out_labels_map[triplet.src_label].emplace_back(triplet);
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<IVertexColumn>(ctx.get(params.v_tag));
if (params.dir == Direction::kOut) {
auto& triplet = labels[0];
auto builder = SDSLEdgeColumnBuilder::builder(
Direction::kOut, triplet, label_props[0].second);
foreach_vertex(
input_vertex_list, [&](size_t index, label_t label, vid_t v) {
if (label == triplet.src_label) {
auto oe_iter = graph.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(nullptr),
shuffle_offset);
return ctx;
} else if (params.dir == Direction::kIn) {
auto& triplet = labels[0];
auto builder = SDSLEdgeColumnBuilder::builder(Direction::kIn, triplet,
label_props[0].second);
foreach_vertex(
input_vertex_list, [&](size_t index, label_t label, vid_t v) {
if (label == triplet.dst_label) {
auto ie_iter = graph.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(nullptr),
shuffle_offset);
return ctx;
}
} else if (labels.size() > 1 || labels.size() == 0) {
auto& input_vertex_list =
*std::dynamic_pointer_cast<IVertexColumn>(ctx.get(params.v_tag));
auto builder = 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 (const auto& triplet : out_labels_map[label]) {
auto oe_iter = graph.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 (const auto& triplet : in_labels_map[label]) {
auto ie_iter = graph.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(nullptr),
shuffle_offset);
return ctx;
}
} else if (params.dir == Direction::kBoth) {
if (labels.size() == 1) {
auto builder =
BDSLEdgeColumnBuilder::builder(labels[0], label_props[0].second);
auto& input_vertex_list =
*std::dynamic_pointer_cast<IVertexColumn>(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 = graph.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 = graph.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(nullptr),
shuffle_offset);
return ctx;
} else {
auto builder = BDMLEdgeColumnBuilder::builder(label_props);
auto& input_vertex_list =
*std::dynamic_pointer_cast<IVertexColumn>(ctx.get(params.v_tag));
foreach_vertex(
input_vertex_list, [&](size_t index, label_t label, vid_t v) {
for (const auto& triplet : out_labels_map[label]) {
auto oe_iter = graph.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();
}
}
for (const auto& triplet : in_labels_map[label]) {
auto ie_iter = graph.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(nullptr),
shuffle_offset);
return ctx;
}
}
}
LOG(ERROR) << "not support" << params.labels.size() << " "
<< (int) params.dir;
RETURN_UNSUPPORTED_ERROR("not support" +
std::to_string(params.labels.size()) + " " +
std::to_string((int) params.dir));
}