@@ -4,7 +4,9 @@ use std::collections::BTreeMap;
44use std:: fmt:: Debug ;
55use std:: sync:: Arc ;
66
7- use crate :: ir:: { Argument , ContextField , FieldRef , IRQuery , IRVertex , Operation } ;
7+ use crate :: ir:: {
8+ Argument , ContextField , FieldRef , IREdge , IRFold , IRQuery , IRVertex , Operation , Recursive ,
9+ } ;
810use crate :: {
911 interpreter:: basic_adapter:: { ContextIterator , ContextOutcomeIterator } ,
1012 ir:: { Eid , FieldValue , IRQueryComponent , Vid } ,
@@ -102,7 +104,7 @@ pub trait VertexInfo {
102104 // optional, recursed, or folded edge;
103105 // recursed because recursion always starts at depth 0
104106 // TODO: What happens if the same edge exists more than once in a given scope?
105- // fn optional_edge(&self, edge_name: &str) -> Option<EdgeInfo>;
107+ fn optional_edge ( & self , edge_name : & str ) -> Option < EdgeInfo > ;
106108}
107109
108110#[ non_exhaustive]
@@ -177,6 +179,40 @@ pub struct LocalQueryInfo {
177179 current_vertex : Vid ,
178180}
179181
182+ impl LocalQueryInfo {
183+ fn make_non_folded_edge_info ( & self , edge : & IREdge ) -> EdgeInfo {
184+ let neighboring_info = NeighboringQueryInfo {
185+ query : self . query . clone ( ) ,
186+ starting_vertex : self . current_vertex ,
187+ neighbor_vertex : edge. to_vid ,
188+ neighbor_path : vec ! [ edge. eid] ,
189+ } ;
190+ EdgeInfo {
191+ eid : edge. eid ,
192+ optional : edge. optional ,
193+ recursive : edge. recursive . clone ( ) ,
194+ folded : false ,
195+ destination : neighboring_info,
196+ }
197+ }
198+
199+ fn make_folded_edge_info ( & self , fold : & IRFold ) -> EdgeInfo {
200+ let neighboring_info = NeighboringQueryInfo {
201+ query : self . query . clone ( ) ,
202+ starting_vertex : self . current_vertex ,
203+ neighbor_vertex : fold. to_vid ,
204+ neighbor_path : vec ! [ fold. eid] ,
205+ } ;
206+ EdgeInfo {
207+ eid : fold. eid ,
208+ optional : true ,
209+ recursive : None ,
210+ folded : true ,
211+ destination : neighboring_info,
212+ }
213+ }
214+ }
215+
180216impl VertexInfo for LocalQueryInfo {
181217 #[ inline]
182218 fn current_vertex ( & self ) -> & IRVertex {
@@ -202,6 +238,7 @@ impl VertexInfo for LocalQueryInfo {
202238 return Some ( DynamicallyResolvedValue {
203239 query : self . query . clone ( ) ,
204240 vid : vertex. vid ,
241+ resolve_on_component : self . query . query . indexed_query . vids [ & vertex. vid ] . clone ( ) ,
205242 context_field : context_field. clone ( ) ,
206243 is_multiple : false ,
207244 } ) ;
@@ -210,6 +247,7 @@ impl VertexInfo for LocalQueryInfo {
210247 return Some ( DynamicallyResolvedValue {
211248 query : self . query . clone ( ) ,
212249 vid : vertex. vid ,
250+ resolve_on_component : self . query . query . indexed_query . vids [ & vertex. vid ] . clone ( ) ,
213251 context_field : context_field. clone ( ) ,
214252 is_multiple : true ,
215253 } ) ;
@@ -236,23 +274,27 @@ impl VertexInfo for LocalQueryInfo {
236274 && edge. recursive . is_none ( )
237275 && edge. edge_name . as_ref ( ) == edge_name
238276 } ) ;
239- if let Some ( matching_edge) = first_matching_edge {
240- let neighboring_info = NeighboringQueryInfo {
241- query : self . query . clone ( ) ,
242- starting_vertex : self . current_vertex ,
243- neighbor_vertex : matching_edge. to_vid ,
244- neighbor_path : vec ! [ matching_edge. eid] ,
245- } ;
246- Some ( EdgeInfo {
247- eid : matching_edge. eid ,
248- optional : false ,
249- recursive : None ,
250- folded : false ,
251- destination : neighboring_info,
277+ first_matching_edge. map ( |edge| self . make_non_folded_edge_info ( edge. as_ref ( ) ) )
278+ }
279+
280+ fn optional_edge ( & self , edge_name : & str ) -> Option < EdgeInfo > {
281+ // TODO: What happens if the same edge exists more than once in a given scope?
282+ let component = self . current_component ( ) ;
283+ let current_vertex = self . current_vertex ( ) ;
284+ let first_matching_edge = component. edges . values ( ) . find ( |edge| {
285+ edge. from_vid == current_vertex. vid && edge. edge_name . as_ref ( ) == edge_name
286+ } ) ;
287+ first_matching_edge
288+ . map ( |edge| self . make_non_folded_edge_info ( edge. as_ref ( ) ) )
289+ . or_else ( || {
290+ component
291+ . folds
292+ . values ( )
293+ . find ( |fold| {
294+ fold. from_vid == current_vertex. vid && fold. edge_name . as_ref ( ) == edge_name
295+ } )
296+ . map ( |fold| self . make_folded_edge_info ( fold. as_ref ( ) ) )
252297 } )
253- } else {
254- None
255- }
256298 }
257299}
258300
@@ -261,7 +303,7 @@ impl VertexInfo for LocalQueryInfo {
261303pub struct EdgeInfo {
262304 eid : Eid ,
263305 optional : bool ,
264- recursive : Option < usize > , // TODO: perhaps a better inner type, to represent "no-limit" too?
306+ recursive : Option < Recursive > ,
265307 folded : bool ,
266308 destination : NeighboringQueryInfo ,
267309}
@@ -281,6 +323,44 @@ pub struct NeighboringQueryInfo {
281323 neighbor_path : Vec < Eid > ,
282324}
283325
326+ impl NeighboringQueryInfo {
327+ fn make_non_folded_edge_info ( & self , edge : & IREdge ) -> EdgeInfo {
328+ let mut neighbor_path = self . neighbor_path . clone ( ) ;
329+ neighbor_path. push ( edge. eid ) ;
330+ let neighboring_info = NeighboringQueryInfo {
331+ query : self . query . clone ( ) ,
332+ starting_vertex : self . starting_vertex ,
333+ neighbor_vertex : edge. to_vid ,
334+ neighbor_path,
335+ } ;
336+ EdgeInfo {
337+ eid : edge. eid ,
338+ optional : edge. optional ,
339+ recursive : edge. recursive . clone ( ) ,
340+ folded : false ,
341+ destination : neighboring_info,
342+ }
343+ }
344+
345+ fn make_folded_edge_info ( & self , fold : & IRFold ) -> EdgeInfo {
346+ let mut neighbor_path = self . neighbor_path . clone ( ) ;
347+ neighbor_path. push ( fold. eid ) ;
348+ let neighboring_info = NeighboringQueryInfo {
349+ query : self . query . clone ( ) ,
350+ starting_vertex : self . starting_vertex ,
351+ neighbor_vertex : fold. to_vid ,
352+ neighbor_path,
353+ } ;
354+ EdgeInfo {
355+ eid : fold. eid ,
356+ optional : true ,
357+ recursive : None ,
358+ folded : true ,
359+ destination : neighboring_info,
360+ }
361+ }
362+ }
363+
284364impl VertexInfo for NeighboringQueryInfo {
285365 #[ inline]
286366 fn current_vertex ( & self ) -> & IRVertex {
@@ -330,6 +410,7 @@ impl VertexInfo for NeighboringQueryInfo {
330410 query : self . query . clone ( ) ,
331411 vid : vertex. vid ,
332412 context_field : context_field. clone ( ) ,
413+ resolve_on_component : self . query . query . indexed_query . vids [ & self . starting_vertex ] . clone ( ) ,
333414 is_multiple : false ,
334415 } ) ;
335416 }
@@ -340,6 +421,7 @@ impl VertexInfo for NeighboringQueryInfo {
340421 query : self . query . clone ( ) ,
341422 vid : vertex. vid ,
342423 context_field : context_field. clone ( ) ,
424+ resolve_on_component : self . query . query . indexed_query . vids [ & self . starting_vertex ] . clone ( ) ,
343425 is_multiple : true ,
344426 } ) ;
345427 }
@@ -365,37 +447,35 @@ impl VertexInfo for NeighboringQueryInfo {
365447 && edge. recursive . is_none ( )
366448 && edge. edge_name . as_ref ( ) == edge_name
367449 } ) ;
368- if let Some ( matching_edge) = first_matching_edge {
369- let mut neighbor_path = self . neighbor_path . clone ( ) ;
370- neighbor_path. push ( matching_edge. eid ) ;
371- let neighboring_info = NeighboringQueryInfo {
372- query : self . query . clone ( ) ,
373- starting_vertex : self . starting_vertex ,
374- neighbor_vertex : matching_edge. to_vid ,
375- neighbor_path,
376- } ;
377- Some ( EdgeInfo {
378- eid : matching_edge. eid ,
379- optional : false ,
380- recursive : None ,
381- folded : false ,
382- destination : neighboring_info,
383- } )
384- } else {
385- None
386- }
450+ first_matching_edge. map ( |edge| self . make_non_folded_edge_info ( edge. as_ref ( ) ) )
387451 }
388452
389- // fn optional_edge(&self, edge_name: &str) -> Option<EdgeInfo> {
390- // // similar concerns as above in `required_edge()`
391- // todo!()
392- // }
453+ fn optional_edge ( & self , edge_name : & str ) -> Option < EdgeInfo > {
454+ // TODO: What happens if the same edge exists more than once in a given scope?
455+ let component = self . current_component ( ) ;
456+ let current_vertex = self . current_vertex ( ) ;
457+ let first_matching_edge = component. edges . values ( ) . find ( |edge| {
458+ edge. from_vid == current_vertex. vid && edge. edge_name . as_ref ( ) == edge_name
459+ } ) ;
460+ first_matching_edge
461+ . map ( |edge| self . make_non_folded_edge_info ( edge. as_ref ( ) ) )
462+ . or_else ( || {
463+ component
464+ . folds
465+ . values ( )
466+ . find ( |fold| {
467+ fold. from_vid == current_vertex. vid && fold. edge_name . as_ref ( ) == edge_name
468+ } )
469+ . map ( |fold| self . make_folded_edge_info ( fold. as_ref ( ) ) )
470+ } )
471+ }
393472}
394473
395474#[ non_exhaustive]
396475pub struct DynamicallyResolvedValue {
397476 query : QueryInfo ,
398477 vid : Vid ,
478+ resolve_on_component : Arc < IRQueryComponent > ,
399479 context_field : ContextField ,
400480 is_multiple : bool ,
401481}
@@ -410,11 +490,11 @@ impl DynamicallyResolvedValue {
410490 adapter : & mut AdapterT ,
411491 contexts : ContextIterator < ' vertex , VertexT > ,
412492 ) -> ContextOutcomeIterator < ' vertex , VertexT , CandidateValue < FieldValue > > {
413- let component = & self . query . query . indexed_query . vids [ & self . vid ] . clone ( ) ;
493+ // let component = &self.query.query.indexed_query.vids[&self.vid].clone();
414494 let iterator = compute_context_field_with_separate_value (
415495 adapter,
416496 & mut self . query ,
417- component ,
497+ & self . resolve_on_component ,
418498 & self . context_field ,
419499 contexts,
420500 ) ;
0 commit comments