Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit 4fba249

Browse files
committed
Updated CLI and Added InMemory graph benchmark
1 parent 4bf3a97 commit 4fba249

18 files changed

Lines changed: 651 additions & 214 deletions

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@
184184
<configuration>
185185
<includeSystemScope>true</includeSystemScope>
186186
<addResources>true</addResources>
187-
<mainClass>benchmark.Neo4jBenchmark</mainClass>
187+
<mainClass>benchmark.GraphBenchmark</mainClass>
188188
</configuration>
189189
<executions>
190190
<execution>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package benchmark;
2+
3+
import iguana.utils.input.Edge;
4+
import iguana.utils.input.GraphInput;
5+
import iguana.utils.input.InMemGraphInput;
6+
7+
import java.io.File;
8+
import java.io.IOException;
9+
import java.nio.file.Files;
10+
import java.nio.file.Paths;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.stream.Collectors;
14+
import java.util.stream.Stream;
15+
16+
import static java.util.stream.Collectors.*;
17+
18+
public class BenchmarkGraphInMemory extends BenchmarkGraphStorage {
19+
20+
private List<Integer> finalVertices = null;
21+
private final List<List<Edge>> adjacencyList = new ArrayList<>();
22+
23+
@Override
24+
public void loadGraph(String path) throws IOException {
25+
try (var lines = Files.lines(Paths.get(path + File.separator + "nodes.csv"))) {
26+
finalVertices = lines.skip(1).map(Integer::parseInt).collect(Collectors.toList());
27+
}
28+
try (var lines = Files.lines(Paths.get(path + File.separator + "edges.csv"))) {
29+
var graph = lines
30+
.skip(1)
31+
.map(it -> it.split(" "))
32+
.flatMap(it -> Stream.of(it, new String[]{it[2], it[1] + "_r", it[0]}))
33+
.collect(
34+
groupingBy(e -> Integer.parseInt(e[0]),
35+
mapping(e -> new Edge(e[1], Integer.parseInt(e[2])), toList()))
36+
);
37+
int nodesCount = finalVertices.size();
38+
for (var i = 0; i < nodesCount; i++) {
39+
adjacencyList.add(graph.getOrDefault(i, new ArrayList<>()));
40+
}
41+
}
42+
}
43+
44+
@Override
45+
public GraphInput getGraphInput(Stream<Integer> startVertices) {
46+
return new InMemGraphInput(adjacencyList, startVertices, finalVertices);
47+
}
48+
49+
@Override
50+
protected void close() {
51+
}
52+
53+
@Override
54+
public String toString() {
55+
return "INMEM";
56+
}
57+
}
Lines changed: 39 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import apoc.export.csv.ImportCsv;
66
import apoc.help.Help;
77
import apoc.periodic.Periodic;
8-
import org.iguana.grammar.Grammar;
8+
import iguana.utils.input.GraphInput;
9+
import iguana.utils.input.Neo4jBenchmarkInput;
910
import org.neo4j.configuration.GraphDatabaseSettings;
1011
import org.neo4j.configuration.connectors.BoltConnector;
1112
import org.neo4j.dbms.api.DatabaseManagementService;
@@ -19,61 +20,22 @@
1920
import org.neo4j.kernel.api.procedure.GlobalProcedures;
2021
import org.neo4j.kernel.internal.GraphDatabaseAPI;
2122

22-
import java.io.File;
23-
import java.io.FileNotFoundException;
24-
import java.io.IOException;
23+
import java.io.*;
24+
import java.nio.file.Files;
25+
import java.nio.file.Paths;
2526
import java.util.List;
2627
import java.util.function.BiFunction;
28+
import java.util.stream.Stream;
2729

2830
import static java.util.Arrays.asList;
2931
import static org.neo4j.configuration.GraphDatabaseSettings.DEFAULT_DATABASE_NAME;
3032

31-
public abstract class Neo4jBenchmark {
32-
33-
protected static String RESULTS_DIR = "results";
34-
35-
// args[0] - benchmarkType
36-
// args[1] - nodeNumber
37-
// args[2] - number of warm up iteration
38-
// args[3] - total number of iterations
39-
// args[4] - path to dataset (graph)
40-
// args[5] - path to grammar
41-
// args[6] - dataset name = name of file with results
42-
public static void main(String[] args) throws IOException {
43-
Neo4jBenchmark benchmark = benchmarkByType(args[0], Integer.parseInt(args[1]));
44-
benchmark.loadGraph(args[4]);
45-
benchmark.loadGrammar(args[5]);
46-
benchmark.benchmark(parseSettings(new String[]{args[2], args[3], args[6]}));
47-
benchmark.removeData();
48-
benchmark.managementService.shutdown();
49-
}
50-
private static Neo4jBenchmark benchmarkByType(String type, int nodesCount) {
51-
return switch (type) {
52-
// AP - All Pairs; MS - Multiple Sources
53-
case "REACHABILITY_AP" -> new ReachabilityBenchmark(nodesCount);
54-
// case "REACHABILITY_MS" -> new ReachabilityBenchmark();
55-
case "PATH_AP" -> new PathBenchmark(nodesCount);
56-
// case "PATH_MS" -> new PathBenchmark();
57-
default -> throw new IllegalArgumentException("Illegal benchmark type");
58-
};
59-
}
33+
public class BenchmarkGraphNeo4j extends BenchmarkGraphStorage {
6034

61-
/**
62-
* @param args array contains string params:
63-
* args[0] - warmUpIterations
64-
* args[1] - measurementsIterations
65-
* args[2] - datasetName
66-
* @return {@link BenchmarkSettings} instance
67-
*/
68-
private static BenchmarkSettings parseSettings(String[] args) {
69-
return new BenchmarkSettings(
70-
Integer.parseInt(args[0]),
71-
Integer.parseInt(args[1]),
72-
args[2]);
73-
}
35+
private int nodesCount;
36+
37+
BenchmarkGraphNeo4j() {
7438

75-
Neo4jBenchmark(int nodesCount) {
76-
this.nodesCount = nodesCount;
7739
}
7840

7941
private final BiFunction<Relationship, Direction, String> relationship2Label =
@@ -86,9 +48,8 @@ private static BenchmarkSettings parseSettings(String[] args) {
8648
private final File databaseDirectory = new File("target/neo4j-hello-db");
8749
private GraphDatabaseService graphDb;
8850
private DatabaseManagementService managementService;
89-
private Grammar grammar;
90-
private final int nodesCount;
91-
public void registerProcedure(GraphDatabaseService graphDb, List<Class<?>> procedures) {
51+
52+
private void registerProcedure(GraphDatabaseService graphDb, List<Class<?>> procedures) {
9253
GlobalProcedures globalProcedures = ((GraphDatabaseAPI) graphDb).getDependencyResolver().resolveDependency(GlobalProcedures.class);
9354
for (Class<?> procedure : procedures) {
9455
try {
@@ -101,7 +62,15 @@ public void registerProcedure(GraphDatabaseService graphDb, List<Class<?>> proce
10162
}
10263
}
10364

104-
private void loadGraph(String pathToDataset) throws IOException {
65+
private Neo4jBenchmarkInput graphInput = null;
66+
67+
@Override
68+
public void loadGraph(String path) throws IOException {
69+
70+
try (var lines = Files.lines(Paths.get(path + File.separatorChar + "nodes.csv"))) {
71+
nodesCount = (int) lines.count();
72+
}
73+
10574
FileUtils.deleteRecursively(databaseDirectory);
10675
managementService =
10776
new DatabaseManagementServiceBuilder(databaseDirectory)
@@ -124,50 +93,45 @@ private void loadGraph(String pathToDataset) throws IOException {
12493
Periodic.class
12594
));
12695

96+
String neo4jPath = new File(path).getAbsolutePath();
12797
try (Transaction tx = graphDb.beginTx()) {
12898
tx.execute("CALL apoc.import.csv(" +
129-
"[{fileName: 'FILE:///" + pathToDataset + "nodes.csv', labels: ['Node']}], " +
130-
"[{fileName: 'FILE:///" + pathToDataset + "edges.csv'}], " +
99+
"[{fileName: 'FILE:///" + neo4jPath + File.separator + "nodes.csv', labels: ['Node']}], " +
100+
"[{fileName: 'FILE:///" + neo4jPath + File.separator + "edges.csv'}], " +
131101
"{delimiter: ' ', stringIds: false}" +
132102
")");
133103
tx.commit();
134104
}
135105
System.out.println("Graph loaded");
136106
}
137107

138-
private void loadGrammar(String pathToGrammar) {
139-
try {
140-
grammar = Grammar.load(pathToGrammar, "json");
141-
} catch (FileNotFoundException e) {
142-
throw new RuntimeException("No grammar file is present");
143-
}
108+
@Override
109+
public GraphInput getGraphInput(Stream<Integer> startVertices) {
110+
graphInput = new Neo4jBenchmarkInput(graphDb, relationship2Label, startVertices, nodesCount);
111+
return graphInput;
144112
}
145113

146-
protected abstract void benchmark(BenchmarkSettings settings) throws IOException;
114+
@Override
115+
protected void onIterationFinish() {
116+
graphInput.close();
117+
graphInput = null;
118+
}
147119

148-
private void removeData() {
120+
@Override
121+
protected void close() {
149122
try (Transaction tx = graphDb.beginTx()) {
150123
tx.getAllNodes().forEach(node -> {
151124
node.getRelationships().forEach(Relationship::delete);
152125
node.delete();
153126
});
154127
tx.commit();
155128
}
129+
managementService.shutdown();
156130
}
157131

158-
protected BiFunction<Relationship, Direction, String> getRelationship2Label() {
159-
return relationship2Label;
160-
}
161-
162-
protected GraphDatabaseService getGraphDb() {
163-
return graphDb;
164-
}
165-
166-
protected Grammar getGrammar() {
167-
return grammar;
132+
@Override
133+
public String toString() {
134+
return "NEO4J";
168135
}
169136

170-
protected int getNodesCount() {
171-
return nodesCount;
172-
}
173137
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package benchmark;
2+
3+
import iguana.utils.input.GraphInput;
4+
5+
import java.io.IOException;
6+
import java.util.stream.Stream;
7+
8+
public abstract class BenchmarkGraphStorage {
9+
10+
public static BenchmarkGraphStorage createBenchmarkStorage(GraphStorage storageType) {
11+
return switch (storageType) {
12+
case NEO4J -> new BenchmarkGraphNeo4j();
13+
case IN_MEMORY -> new BenchmarkGraphInMemory();
14+
};
15+
}
16+
17+
public abstract void loadGraph(String path) throws IOException;
18+
19+
public abstract GraphInput getGraphInput(Stream<Integer> startVertices);
20+
21+
protected void onIterationStart() {
22+
}
23+
24+
protected void onIterationFinish() {
25+
}
26+
27+
protected abstract void close();
28+
29+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package benchmark;
2+
3+
import iguana.utils.input.GraphInput;
4+
import org.iguana.parser.IguanaParser;
5+
6+
public abstract class BenchmarkProblem {
7+
8+
public static BenchmarkProblem createBenchmarkProblem(Problem problem) {
9+
return switch (problem) {
10+
case REACHABILITY -> new BenchmarkProblemReachability();
11+
case ALL_PATHS -> new BenchmarkProblemAllPaths();
12+
};
13+
}
14+
15+
public abstract void runAlgo(IguanaParser parser, GraphInput input);
16+
17+
public abstract long getResult();
18+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package benchmark;
2+
3+
import iguana.utils.input.GraphInput;
4+
import org.iguana.parser.IguanaParser;
5+
import org.iguana.parser.Pair;
6+
import org.iguana.parser.ParseOptions;
7+
import org.iguana.sppf.NonterminalNode;
8+
9+
import java.util.Map;
10+
import java.util.stream.Stream;
11+
12+
public class BenchmarkProblemAllPaths extends BenchmarkProblem {
13+
14+
private Map<Pair, NonterminalNode> parseResults = null;
15+
@Override
16+
public void runAlgo(IguanaParser parser, GraphInput input) {
17+
parseResults = parser.getSPPF(input);
18+
}
19+
20+
@Override
21+
public long getResult() {
22+
return parseResults.size();
23+
}
24+
25+
@Override
26+
public String toString() {
27+
return "SPPF";
28+
}
29+
30+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package benchmark;
2+
3+
import iguana.utils.input.GraphInput;
4+
import org.iguana.parser.IguanaParser;
5+
import org.iguana.parser.Pair;
6+
import org.iguana.parser.ParseOptions;
7+
8+
import java.util.stream.Stream;
9+
10+
public class BenchmarkProblemReachability extends BenchmarkProblem {
11+
12+
private Stream<Pair> parseResults = null;
13+
14+
@Override
15+
public void runAlgo(IguanaParser parser, GraphInput input) {
16+
parseResults = parser.getReachabilities(input,
17+
new ParseOptions
18+
.Builder()
19+
.setAmbiguous(false)
20+
.build());
21+
}
22+
23+
@Override
24+
public long getResult() {
25+
return parseResults.count();
26+
}
27+
28+
@Override
29+
public String toString() {
30+
return "REACHABILITY";
31+
}
32+
33+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package benchmark;
2+
3+
import java.util.List;
4+
5+
public abstract class BenchmarkScenario {
6+
7+
public static BenchmarkScenario createBenchmarkScenario(BenchmarkSettings.ScenarioSettings scenario) {
8+
return switch (scenario.getScenario()) {
9+
case ALL_PAIRS -> new BenchmarkScenarioAllPairs(scenario.getNodesCount());
10+
case MULTIPLE_SOURCES -> new BenchmarkScenarioMultipleSources(scenario.getPath());
11+
};
12+
}
13+
14+
public abstract String getCsvHeader();
15+
public abstract String getCsvRecord(int chunkIndex, double stepPrepareTime, double stepRunTime, long result);
16+
public abstract List<List<Integer>> getStartVerticesChunks();
17+
18+
}

0 commit comments

Comments
 (0)