1515
1616import java .io .File ;
1717import java .io .IOException ;
18+ import java .nio .file .Path ;
1819import java .util .concurrent .TimeUnit ;
1920
2021import org .apache .commons .io .FileUtils ;
2122import org .assertj .core .util .Files ;
23+ import org .eclipse .rdf4j .benchmark .common .BenchmarkQuery ;
2224import org .eclipse .rdf4j .benchmark .common .ThemeQueryCatalog ;
25+ import org .eclipse .rdf4j .benchmark .common .plan .FeatureFlagCollector ;
26+ import org .eclipse .rdf4j .benchmark .common .plan .QueryPlanCapture ;
27+ import org .eclipse .rdf4j .benchmark .common .plan .QueryPlanCaptureContext ;
2328import org .eclipse .rdf4j .benchmark .rio .util .ThemeDataSetGenerator ;
2429import org .eclipse .rdf4j .benchmark .rio .util .ThemeDataSetGenerator .Theme ;
2530import org .eclipse .rdf4j .common .transaction .IsolationLevels ;
2631import org .eclipse .rdf4j .query .explanation .Explanation ;
32+ import org .eclipse .rdf4j .queryrender .sparql .TupleExprIRRenderer ;
2733import org .eclipse .rdf4j .repository .sail .SailRepository ;
2834import org .eclipse .rdf4j .repository .sail .SailRepositoryConnection ;
2935import org .eclipse .rdf4j .repository .util .RDFInserter ;
3036import org .eclipse .rdf4j .sail .lmdb .LmdbStore ;
37+ import org .eclipse .rdf4j .sail .lmdb .config .LmdbStoreConfig ;
3138import org .junit .jupiter .api .Disabled ;
3239import org .junit .jupiter .api .Test ;
3340import org .openjdk .jmh .annotations .Benchmark ;
5663@ OutputTimeUnit (TimeUnit .MILLISECONDS )
5764public class ThemeQueryBenchmark {
5865
66+ private static final String STORE_NAME = "lmdb" ;
67+
5968 @ Param ({ "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" })
6069 public int z_queryIndex ;
6170
@@ -73,6 +82,8 @@ public class ThemeQueryBenchmark {
7382
7483 private File dataDir ;
7584 private SailRepository repository ;
85+ private LmdbStore store ;
86+ private LmdbStoreConfig storeConfig ;
7687 private Theme theme ;
7788 private String query ;
7889 private long expected ;
@@ -91,8 +102,13 @@ public void setup() throws IOException {
91102 query = ThemeQueryCatalog .queryFor (theme , z_queryIndex );
92103 expected = ThemeQueryCatalog .expectedCountFor (theme , z_queryIndex );
93104 dataDir = Files .newTemporaryFolder ();
94- repository = new SailRepository (new LmdbStore (dataDir , ConfigUtil .createConfig ()));
105+ storeConfig = ConfigUtil .createConfig ();
106+ store = new LmdbStore (dataDir , storeConfig );
107+ repository = new SailRepository (store );
95108 loadData ();
109+ if (QueryPlanCapture .isCaptureEnabled ()) {
110+ captureQueryPlanSnapshot ();
111+ }
96112 }
97113
98114 private void loadData () throws IOException {
@@ -104,6 +120,47 @@ private void loadData() throws IOException {
104120 }
105121 }
106122
123+ private void captureQueryPlanSnapshot () throws IOException {
124+ BenchmarkQuery benchmarkQuery = ThemeQueryCatalog .benchmarkQueryFor (theme , z_queryIndex );
125+ FeatureFlagCollector featureFlags = new FeatureFlagCollector ()
126+ .addValue ("themeBenchmark.themeName" , () -> themeName )
127+ .addValue ("themeBenchmark.queryIndex" , () -> z_queryIndex )
128+ .addReflectiveGetter ("lmdbStore.writable" , store , "isWritable" )
129+ .addReflectiveGetter ("lmdbConfig.tripleIndexes" , storeConfig , "getTripleIndexes" )
130+ .addReflectiveGetter ("lmdbConfig.forceSync" , storeConfig , "getForceSync" )
131+ .addReflectiveField ("lmdbConfig.autoGrow" , storeConfig , "autoGrow" )
132+ .addReflectiveGetter ("lmdbConfig.valueDbSize" , storeConfig , "getValueDBSize" )
133+ .addReflectiveGetter ("lmdbConfig.tripleDbSize" , storeConfig , "getTripleDBSize" );
134+ QueryPlanCapture .registerConfiguredFeatureFlags (featureFlags );
135+
136+ QueryPlanCaptureContext context = QueryPlanCaptureContext .builder ()
137+ .outputDirectory (QueryPlanCapture .resolveOutputDirectory ().resolve (STORE_NAME ))
138+ .queryId (STORE_NAME + "-" + themeName + "-q" + z_queryIndex )
139+ .queryString (query )
140+ .benchmark ("ThemeQueryBenchmark" )
141+ .addMetadata ("store" , STORE_NAME )
142+ .addMetadata ("theme" , themeName )
143+ .addMetadata ("queryIndex" , Integer .toString (z_queryIndex ))
144+ .addMetadata ("queryName" , benchmarkQuery .getName ())
145+ .addMetadata ("expectedCount" , Long .toString (expected ))
146+ .addMetadata (QueryPlanCapture .metadataFromSystemProperties ())
147+ .featureFlagCollector (featureFlags )
148+ .tupleExprRenderer (this ::renderTupleExprWithIr )
149+ .build ();
150+
151+ try (SailRepositoryConnection connection = repository .getConnection ()) {
152+ Path snapshotPath = new QueryPlanCapture ()
153+ .captureAndWrite (context , () -> connection .prepareTupleQuery (query ));
154+ System .out .println ("Query plan snapshot written to: " + snapshotPath );
155+ }
156+ }
157+
158+ private String renderTupleExprWithIr (org .eclipse .rdf4j .query .algebra .TupleExpr tupleExpr ) {
159+ TupleExprIRRenderer .Config config = new TupleExprIRRenderer .Config ();
160+ config .verifyRoundTrip = false ;
161+ return new TupleExprIRRenderer (config ).render (tupleExpr );
162+ }
163+
107164 @ TearDown (Level .Trial )
108165 public void tearDown () throws IOException {
109166 repository .shutDown ();
0 commit comments