55import org .neo4j .graphalgo .WeightedPath ;
66import org .neo4j .graphalgo .impl .util .PathImpl ;
77import org .neo4j .graphdb .*;
8- import org .neo4j .graphdb .traversal .Evaluators ;
9- import org .neo4j .graphdb .traversal .InitialBranchState ;
10- import org .neo4j .graphdb .traversal .Traverser ;
11- import org .neo4j .graphdb .traversal .Uniqueness ;
8+ import org .neo4j .graphdb .traversal .*;
129import org .neo4j .logging .Log ;
1310import org .neo4j .procedure .*;
1411
@@ -33,14 +30,12 @@ public class FindAnyOnePath {
3330
3431
3532 @ Procedure (name = "bytecodedl.findOnePath" , mode = Mode .READ )
36- @ Description ("find one path from start to end between minlength and maxlength, also show first multi dispatch" )
37- public Stream <PathRecord > findOnePath (@ Name ("start" ) Node start , @ Name ("end" ) Node end , @ Name ("maxLength" ) String maxLength , @ Name ( "minLength" ) String minLength , @ Name ("callProperty" ) String callProperty ){
33+ @ Description ("find one path from start to end under maxlength, also show first multi dispatch" )
34+ public Stream <PathRecord > findOnePath (@ Name ("start" ) Node start , @ Name ("end" ) Node end , @ Name ("maxLength" ) long maxLength , @ Name ("callProperty" ) String callProperty ){
3835 final Traverser traverse = tx .traversalDescription ()
39- //.depthFirst()
4036 .breadthFirst ()
41- .evaluator (new FindAnyOneEvaluator (end , maxLength , minLength , log ))
42- .expand (new FindAnyOneExpander (PathExpanders .forTypeAndDirection (RelationshipType .withName ("Call" ), Direction .OUTGOING ), log ), new InitialBranchState .State <Boolean >(false , false ))
43- //.expand(PathExpanders.forTypeAndDirection( RelationshipType.withName("Call"), Direction.OUTGOING ))
37+ .evaluator (Evaluators .toDepth ((int )maxLength ))
38+ .expand (PathExpanders .forTypeAndDirection (RelationshipType .withName ("Call" ), Direction .OUTGOING ))
4439 .uniqueness (Uniqueness .NODE_GLOBAL )
4540 .traverse (start );
4641
@@ -59,44 +54,37 @@ public Stream<PathRecord> findOnePath(@Name("start") Node start, @Name("end") No
5954 }
6055 }
6156
62- // @Procedure(name = "bytecodedl.dijkstra", mode = Mode.READ)
63- // @Description("find one path from start to end between minlength and maxlength, also show first multi dispatch")
64- // public Stream<PathRecord> dijkstra(
65- // @Name("startNode") Node startNode,
66- // @Name("endNode") Node endNode,
67- // @Name("weightPropertyName") String weightPropertyName,
68- // @Name(value = "defaultWeight", defaultValue = "NaN") double defaultWeight,
69- // @Name(value = "numberOfWantedPaths", defaultValue = "1") long numberOfWantedPaths
70- // ){
71- // PathFinder<WeightedPath> algo = GraphAlgoFactory.dijkstra(
72- // buildPathExpander(),
73- // (relationship, direction) -> Util.toDouble(relationship.getProperty(weightPropertyName, defaultWeight)),
74- // (int)numberOfWantedPaths
75- // );
76- // Iterable<WeightedPath> paths = algo.findAllPaths(startNode, endNode);
77- //
78- // Optional<WeightedPath> optionalPath = StreamSupport
79- // .stream(paths.spliterator(), false).findFirst();
80- //
81- // if (optionalPath.isPresent()){
82- // Path path = optionalPath.get();
83- // List<Relationship> multiDispatchRelationship = getFirstMultiDispatch(path, "insn");
84- // List<Path> pathList = multiDispatchRelationship.stream().map(this::relationShipToPath).collect(Collectors.toList());
85- // pathList.add(path);
86- // return pathList.stream().map(PathRecord::new);
87- // }else {
88- // return StreamSupport
89- // .stream(paths.spliterator(), false).map(PathRecord::new);
90- // }
91- // }
92-
93- public PathExpander <Double > buildPathExpander () {
94- // PathExpanderBuilder builder = PathExpanderBuilder.allTypesAndDirections();
95-
96- PathExpanderBuilder builder = PathExpanderBuilder .empty ();
97- builder = builder .add (RelationshipType .withName ("Call" ), Direction .OUTGOING );
98- PathExpander <Double > expander = builder .build ();
99- return expander ;
57+ @ Procedure (name = "bytecodedl.biFindOnePath" , mode = Mode .READ )
58+ @ Description ("find one path from start to end between minlength and maxlength, also show first multi dispatch" )
59+ public Stream <PathRecord > biFindOnePath (@ Name ("start" ) Node start , @ Name ("end" ) Node end , @ Name ("maxLength" ) long maxLength , @ Name ("callProperty" ) String callProperty ){
60+ TraversalDescription base = tx .traversalDescription ().depthFirst ().uniqueness (Uniqueness .RELATIONSHIP_GLOBAL );
61+ PathExpander expander = PathExpanders .forTypeAndDirection (RelationshipType .withName ("Call" ), Direction .OUTGOING );
62+ int maxDepth = (int ) maxLength ;
63+
64+ final Traverser traverse = tx .bidirectionalTraversalDescription ()
65+ .startSide (
66+ base .expand (expander )
67+ .evaluator (Evaluators .toDepth (maxDepth / 2 ))
68+ ).endSide (
69+ base .expand (expander .reverse ())
70+ .evaluator (Evaluators .toDepth (maxDepth - maxDepth / 2 ))
71+ )
72+ .traverse (start , end );
73+
74+ Optional <Path > optionalPath = StreamSupport
75+ .stream (traverse .spliterator (), false ).findFirst ();
76+
77+ if (optionalPath .isPresent ()){
78+ Path path = optionalPath .get ();
79+ // System.out.println(path);
80+ List <Relationship > multiDispatchRelationship = getFirstMultiDispatch (path , callProperty );
81+ List <Path > pathList = multiDispatchRelationship .stream ().map (this ::relationShipToPath ).collect (Collectors .toList ());
82+ pathList .add (path );
83+ return pathList .stream ().map (PathRecord ::new );
84+ }else {
85+ return StreamSupport
86+ .stream (traverse .spliterator (), false ).map (PathRecord ::new );
87+ }
10088 }
10189
10290 public Path relationShipToPath (Relationship relationship ){
0 commit comments