@@ -41,8 +41,11 @@ bl::result<Context> PathExpand::edge_expand_v(const GraphReadInterface& graph,
4141 auto & input_vertex_list =
4242 *std::dynamic_pointer_cast<IVertexColumn>(ctx.get (params.start_tag ));
4343 std::set<label_t > labels;
44- for (auto & label : params.labels ) {
44+ std::vector<std::vector<LabelTriplet>> out_labels_map (
45+ graph.schema ().vertex_label_num ());
46+ for (const auto & label : params.labels ) {
4547 labels.emplace (label.dst_label );
48+ out_labels_map[label.src_label ].emplace_back (label);
4649 }
4750
4851 auto builder = MLVertexColumnBuilder::builder (labels);
@@ -71,17 +74,15 @@ bl::result<Context> PathExpand::edge_expand_v(const GraphReadInterface& graph,
7174 auto label = std::get<0 >(tuple);
7275 auto v = std::get<1 >(tuple);
7376 auto index = std::get<2 >(tuple);
74- for (auto & label_triplet : params.labels ) {
75- if (label_triplet.src_label == label) {
76- auto oe_iter = graph.GetOutEdgeIterator (
77- label_triplet.src_label , v, label_triplet.dst_label ,
78- label_triplet.edge_label );
79-
80- while (oe_iter.IsValid ()) {
81- auto nbr = oe_iter.GetNeighbor ();
82- output.emplace_back (label_triplet.dst_label , nbr, index);
83- oe_iter.Next ();
84- }
77+ for (const auto & label_triplet : out_labels_map[label]) {
78+ auto oe_iter = graph.GetOutEdgeIterator (label_triplet.src_label , v,
79+ label_triplet.dst_label ,
80+ label_triplet.edge_label );
81+
82+ while (oe_iter.IsValid ()) {
83+ auto nbr = oe_iter.GetNeighbor ();
84+ output.emplace_back (label_triplet.dst_label , nbr, index);
85+ oe_iter.Next ();
8586 }
8687 }
8788 }
@@ -90,10 +91,69 @@ bl::result<Context> PathExpand::edge_expand_v(const GraphReadInterface& graph,
9091 ctx.set_with_reshuffle (params.alias , builder.finish (nullptr ),
9192 shuffle_offset);
9293 return ctx;
93- } else if (params.dir == Direction::kBoth ) {
94+ } else if (params.dir == Direction::kIn ) {
95+ auto & input_vertex_list =
96+ *std::dynamic_pointer_cast<IVertexColumn>(ctx.get (params.start_tag ));
9497 std::set<label_t > labels;
98+ std::vector<std::vector<LabelTriplet>> in_labels_map (
99+ graph.schema ().vertex_label_num ());
95100 for (auto & label : params.labels ) {
101+ labels.emplace (label.src_label );
102+ in_labels_map[label.dst_label ].emplace_back (label);
103+ }
104+
105+ auto builder = MLVertexColumnBuilder::builder (labels);
106+ std::vector<std::tuple<label_t , vid_t , size_t >> input;
107+ std::vector<std::tuple<label_t , vid_t , size_t >> output;
108+ foreach_vertex (input_vertex_list,
109+ [&](size_t index, label_t label, vid_t v) {
110+ output.emplace_back (label, v, index);
111+ });
112+ int depth = 0 ;
113+ while (depth < params.hop_upper && (!output.empty ())) {
114+ input.clear ();
115+ std::swap (input, output);
116+ if (depth >= params.hop_lower ) {
117+ for (const auto & tuple : input) {
118+ builder.push_back_vertex ({std::get<0 >(tuple), std::get<1 >(tuple)});
119+ shuffle_offset.push_back (std::get<2 >(tuple));
120+ }
121+ }
122+
123+ if (depth + 1 >= params.hop_upper ) {
124+ break ;
125+ }
126+
127+ for (const auto & tuple : input) {
128+ auto label = std::get<0 >(tuple);
129+ auto v = std::get<1 >(tuple);
130+ auto index = std::get<2 >(tuple);
131+ for (const auto & label_triplet : in_labels_map[label]) {
132+ auto oe_iter = graph.GetInEdgeIterator (label_triplet.dst_label , v,
133+ label_triplet.src_label ,
134+ label_triplet.edge_label );
135+
136+ while (oe_iter.IsValid ()) {
137+ auto nbr = oe_iter.GetNeighbor ();
138+ output.emplace_back (label_triplet.src_label , nbr, index);
139+ oe_iter.Next ();
140+ }
141+ }
142+ }
143+ ++depth;
144+ }
145+ ctx.set_with_reshuffle (params.alias , builder.finish (nullptr ),
146+ shuffle_offset);
147+ return ctx;
148+ } else if (params.dir == Direction::kBoth ) {
149+ std::set<label_t > labels;
150+ std::vector<std::vector<LabelTriplet>> in_labels_map (
151+ graph.schema ().vertex_label_num ()),
152+ out_labels_map (graph.schema ().vertex_label_num ());
153+ for (const auto & label : params.labels ) {
96154 labels.emplace (label.dst_label );
155+ in_labels_map[label.dst_label ].emplace_back (label);
156+ out_labels_map[label.src_label ].emplace_back (label);
97157 }
98158
99159 auto builder = MLVertexColumnBuilder::builder (labels);
@@ -135,27 +195,25 @@ bl::result<Context> PathExpand::edge_expand_v(const GraphReadInterface& graph,
135195 auto label = std::get<0 >(tuple);
136196 auto v = std::get<1 >(tuple);
137197 auto index = std::get<2 >(tuple);
138- for (auto & label_triplet : params.labels ) {
139- if (label_triplet.src_label == label) {
140- auto oe_iter = graph.GetOutEdgeIterator (
141- label_triplet.src_label , v, label_triplet.dst_label ,
142- label_triplet.edge_label );
143-
144- while (oe_iter.IsValid ()) {
145- auto nbr = oe_iter.GetNeighbor ();
146- output.emplace_back (label_triplet.dst_label , nbr, index);
147- oe_iter.Next ();
148- }
198+ for (const auto & label_triplet : out_labels_map[label]) {
199+ auto oe_iter = graph.GetOutEdgeIterator (label_triplet.src_label , v,
200+ label_triplet.dst_label ,
201+ label_triplet.edge_label );
202+
203+ while (oe_iter.IsValid ()) {
204+ auto nbr = oe_iter.GetNeighbor ();
205+ output.emplace_back (label_triplet.dst_label , nbr, index);
206+ oe_iter.Next ();
149207 }
150- if (label_triplet. dst_label == label) {
151- auto ie_iter = graph. GetInEdgeIterator (label_triplet. dst_label , v,
152- label_triplet.src_label ,
153- label_triplet.edge_label );
154- while (ie_iter. IsValid ()) {
155- auto nbr = ie_iter.GetNeighbor ();
156- output. emplace_back (label_triplet. src_label , nbr, index );
157- ie_iter. Next ( );
158- }
208+ }
209+ for ( const auto & label_triplet : in_labels_map[label]) {
210+ auto ie_iter = graph. GetInEdgeIterator ( label_triplet.dst_label , v ,
211+ label_triplet.src_label ,
212+ label_triplet. edge_label );
213+ while ( ie_iter.IsValid ()) {
214+ auto nbr = ie_iter. GetNeighbor ( );
215+ output. emplace_back (label_triplet. src_label , nbr, index );
216+ ie_iter. Next ();
159217 }
160218 }
161219 }
@@ -178,6 +236,13 @@ bl::result<Context> PathExpand::edge_expand_p(const GraphReadInterface& graph,
178236 *std::dynamic_pointer_cast<IVertexColumn>(ctx.get (params.start_tag ));
179237 auto label_sets = input_vertex_list.get_labels_set ();
180238 auto labels = params.labels ;
239+ std::vector<std::vector<LabelTriplet>> out_labels_map (
240+ graph.schema ().vertex_label_num ()),
241+ in_labels_map (graph.schema ().vertex_label_num ());
242+ for (const auto & triplet : labels) {
243+ out_labels_map[triplet.src_label ].emplace_back (triplet);
244+ in_labels_map[triplet.dst_label ].emplace_back (triplet);
245+ }
181246 auto dir = params.dir ;
182247 std::vector<std::pair<std::unique_ptr<PathImpl>, size_t >> input;
183248 std::vector<std::pair<std::unique_ptr<PathImpl>, size_t >> output;
@@ -196,18 +261,16 @@ bl::result<Context> PathExpand::edge_expand_p(const GraphReadInterface& graph,
196261 if (depth + 1 < params.hop_upper ) {
197262 for (auto & [path, index] : input) {
198263 auto end = path->get_end ();
199- for (auto & label_triplet : labels) {
200- if (label_triplet.src_label == end.label_ ) {
201- auto oe_iter = graph.GetOutEdgeIterator (end.label_ , end.vid_ ,
202- label_triplet.dst_label ,
203- label_triplet.edge_label );
204- while (oe_iter.IsValid ()) {
205- std::unique_ptr<PathImpl> new_path = path->expand (
206- label_triplet.edge_label , label_triplet.dst_label ,
207- oe_iter.GetNeighbor ());
208- output.emplace_back (std::move (new_path), index);
209- oe_iter.Next ();
210- }
264+ for (const auto & label_triplet : out_labels_map[end.label_ ]) {
265+ auto oe_iter = graph.GetOutEdgeIterator (end.label_ , end.vid_ ,
266+ label_triplet.dst_label ,
267+ label_triplet.edge_label );
268+ while (oe_iter.IsValid ()) {
269+ std::unique_ptr<PathImpl> new_path =
270+ path->expand (label_triplet.edge_label ,
271+ label_triplet.dst_label , oe_iter.GetNeighbor ());
272+ output.emplace_back (std::move (new_path), index);
273+ oe_iter.Next ();
211274 }
212275 }
213276 }
@@ -244,18 +307,16 @@ bl::result<Context> PathExpand::edge_expand_p(const GraphReadInterface& graph,
244307 if (depth + 1 < params.hop_upper ) {
245308 for (const auto & [path, index] : input) {
246309 auto end = path->get_end ();
247- for (const auto & label_triplet : labels) {
248- if (label_triplet.dst_label == end.label_ ) {
249- auto ie_iter = graph.GetInEdgeIterator (end.label_ , end.vid_ ,
250- label_triplet.src_label ,
251- label_triplet.edge_label );
252- while (ie_iter.IsValid ()) {
253- std::unique_ptr<PathImpl> new_path = path->expand (
254- label_triplet.edge_label , label_triplet.src_label ,
255- ie_iter.GetNeighbor ());
256- output.emplace_back (std::move (new_path), index);
257- ie_iter.Next ();
258- }
310+ for (const auto & label_triplet : in_labels_map[end.label_ ]) {
311+ auto ie_iter = graph.GetInEdgeIterator (end.label_ , end.vid_ ,
312+ label_triplet.src_label ,
313+ label_triplet.edge_label );
314+ while (ie_iter.IsValid ()) {
315+ std::unique_ptr<PathImpl> new_path =
316+ path->expand (label_triplet.edge_label ,
317+ label_triplet.src_label , ie_iter.GetNeighbor ());
318+ output.emplace_back (std::move (new_path), index);
319+ ie_iter.Next ();
259320 }
260321 }
261322 }
@@ -292,30 +353,29 @@ bl::result<Context> PathExpand::edge_expand_p(const GraphReadInterface& graph,
292353 if (depth + 1 < params.hop_upper ) {
293354 for (auto & [path, index] : input) {
294355 auto end = path->get_end ();
295- for (auto & label_triplet : labels) {
296- if (label_triplet.src_label == end.label_ ) {
297- auto oe_iter = graph.GetOutEdgeIterator (end.label_ , end.vid_ ,
298- label_triplet.dst_label ,
299- label_triplet.edge_label );
300- while (oe_iter.IsValid ()) {
301- auto new_path = path->expand (label_triplet.edge_label ,
302- label_triplet.dst_label ,
303- oe_iter.GetNeighbor ());
304- output.emplace_back (std::move (new_path), index);
305- oe_iter.Next ();
306- }
356+ for (const auto & label_triplet : out_labels_map[end.label_ ]) {
357+ auto oe_iter = graph.GetOutEdgeIterator (end.label_ , end.vid_ ,
358+ label_triplet.dst_label ,
359+ label_triplet.edge_label );
360+ while (oe_iter.IsValid ()) {
361+ auto new_path =
362+ path->expand (label_triplet.edge_label ,
363+ label_triplet.dst_label , oe_iter.GetNeighbor ());
364+ output.emplace_back (std::move (new_path), index);
365+ oe_iter.Next ();
307366 }
308- if (label_triplet.dst_label == end.label_ ) {
309- auto ie_iter = graph.GetInEdgeIterator (end.label_ , end.vid_ ,
310- label_triplet.src_label ,
311- label_triplet.edge_label );
312- while (ie_iter.IsValid ()) {
313- auto new_path = path->expand (label_triplet.edge_label ,
314- label_triplet.src_label ,
315- ie_iter.GetNeighbor ());
316- output.emplace_back (std::move (new_path), index);
317- ie_iter.Next ();
318- }
367+ }
368+
369+ for (const auto & label_triplet : in_labels_map[end.label_ ]) {
370+ auto ie_iter = graph.GetInEdgeIterator (end.label_ , end.vid_ ,
371+ label_triplet.src_label ,
372+ label_triplet.edge_label );
373+ while (ie_iter.IsValid ()) {
374+ auto new_path =
375+ path->expand (label_triplet.edge_label ,
376+ label_triplet.src_label , ie_iter.GetNeighbor ());
377+ output.emplace_back (std::move (new_path), index);
378+ ie_iter.Next ();
319379 }
320380 }
321381 }
0 commit comments