1212package org .eclipse .rdf4j .sail .lmdb .benchmark ;
1313
1414import static org .junit .jupiter .api .Assertions .assertEquals ;
15+ import static org .junit .jupiter .api .Assertions .assertTrue ;
1516
1617import java .io .File ;
18+ import java .io .FileInputStream ;
19+ import java .io .FileOutputStream ;
1720import java .io .IOException ;
21+ import java .util .Properties ;
1822import java .util .concurrent .TimeUnit ;
1923
2024import org .apache .commons .io .FileUtils ;
@@ -62,6 +66,9 @@ public class ThemeQueryBenchmark {
6266 private static final File STORE_DIRECTORY = new File ("target" , "lmdb-theme-query-benchmark" );
6367 private static final String TRIPLES_DATA_FILE = "triples/data.mdb" ;
6468 private static final String VALUES_DATA_FILE = "values/data.mdb" ;
69+ private static final String EXPECTED_DB_FILE_SIZES_FILE = "expected-db-file-sizes.properties" ;
70+ private static final String TRIPLES_DATA_SIZE_PROPERTY = "triples.data.mdb.size.bytes" ;
71+ private static final String VALUES_DATA_SIZE_PROPERTY = "values.data.mdb.size.bytes" ;
6572 private static final long EXPECTED_TRIPLES_DATA_SIZE_BYTES = 1500921856L ;
6673 private static final long EXPECTED_VALUES_DATA_SIZE_BYTES = 713687040L ;
6774
@@ -113,16 +120,24 @@ public void setup() throws IOException {
113120 }
114121
115122 private void ensureDataLoadedAndValidated () throws IOException {
116- if (!hasExpectedDbFileSizes ()) {
123+ var expectedDbFileSizes = readExpectedDbFileSizes ();
124+ if (!hasExpectedDbFileSizes (expectedDbFileSizes )) {
117125 rebuildStoreFromScratch ();
126+ expectedDbFileSizes = currentDbFileSizes ();
127+ writeExpectedDbFileSizes (expectedDbFileSizes );
118128 }
119129
120- if (!hasExpectedDbFileSizes ()) {
130+ if (!hasExpectedDbFileSizes (expectedDbFileSizes )) {
131+ var currentDbFileSizes = currentDbFileSizes ();
121132 throw new IllegalStateException ("Unexpected LMDB db file sizes in fixed benchmark store. Expected "
122- + TRIPLES_DATA_FILE + "=" + EXPECTED_TRIPLES_DATA_SIZE_BYTES + " and "
123- + VALUES_DATA_FILE + "=" + EXPECTED_VALUES_DATA_SIZE_BYTES + " but got "
124- + TRIPLES_DATA_FILE + "=" + dbFileSize (TRIPLES_DATA_FILE ) + " and "
125- + VALUES_DATA_FILE + "=" + dbFileSize (VALUES_DATA_FILE ));
133+ + TRIPLES_DATA_FILE + "=" + expectedDbFileSizes .triplesDataSizeBytes + " and "
134+ + VALUES_DATA_FILE + "=" + expectedDbFileSizes .valuesDataSizeBytes + " but got "
135+ + TRIPLES_DATA_FILE + "=" + currentDbFileSizes .triplesDataSizeBytes + " and "
136+ + VALUES_DATA_FILE + "=" + currentDbFileSizes .valuesDataSizeBytes );
137+ }
138+
139+ if (!expectedDbFileSizeFile ().isFile ()) {
140+ writeExpectedDbFileSizes (expectedDbFileSizes );
126141 }
127142 }
128143
@@ -142,9 +157,66 @@ private void rebuildStoreFromScratch() throws IOException {
142157 loadData ();
143158 }
144159
145- private boolean hasExpectedDbFileSizes () {
146- return dbFileSize (TRIPLES_DATA_FILE ) == EXPECTED_TRIPLES_DATA_SIZE_BYTES
147- && dbFileSize (VALUES_DATA_FILE ) == EXPECTED_VALUES_DATA_SIZE_BYTES ;
160+ private DbFileSizes readExpectedDbFileSizes () throws IOException {
161+ var expectedDbFileSizeFile = expectedDbFileSizeFile ();
162+ if (!expectedDbFileSizeFile .isFile ()) {
163+ return defaultExpectedDbFileSizes ();
164+ }
165+ var properties = new Properties ();
166+ try (var inputStream = new FileInputStream (expectedDbFileSizeFile )) {
167+ properties .load (inputStream );
168+ }
169+ try {
170+ return new DbFileSizes (
171+ parseSizeProperty (properties , TRIPLES_DATA_SIZE_PROPERTY ),
172+ parseSizeProperty (properties , VALUES_DATA_SIZE_PROPERTY ));
173+ } catch (IllegalStateException e ) {
174+ System .out .println ("Ignoring invalid expected LMDB size file " + expectedDbFileSizeFile + ": "
175+ + e .getMessage ());
176+ if (!expectedDbFileSizeFile .delete ()) {
177+ System .out .println ("Unable to delete invalid expected LMDB size file: " + expectedDbFileSizeFile );
178+ }
179+ return defaultExpectedDbFileSizes ();
180+ }
181+ }
182+
183+ private void writeExpectedDbFileSizes (DbFileSizes expectedDbFileSizes ) throws IOException {
184+ var properties = new Properties ();
185+ properties .setProperty (TRIPLES_DATA_SIZE_PROPERTY , Long .toString (expectedDbFileSizes .triplesDataSizeBytes ));
186+ properties .setProperty (VALUES_DATA_SIZE_PROPERTY , Long .toString (expectedDbFileSizes .valuesDataSizeBytes ));
187+ try (var outputStream = new FileOutputStream (expectedDbFileSizeFile ())) {
188+ properties .store (outputStream , "Expected LMDB data file sizes for ThemeQueryBenchmark" );
189+ }
190+ }
191+
192+ private long parseSizeProperty (Properties properties , String propertyName ) {
193+ var value = properties .getProperty (propertyName );
194+ if (value == null ) {
195+ throw new IllegalStateException ("Missing property " + propertyName );
196+ }
197+ try {
198+ return Long .parseLong (value );
199+ } catch (NumberFormatException e ) {
200+ throw new IllegalStateException ("Invalid long value for property " + propertyName + ": " + value , e );
201+ }
202+ }
203+
204+ private DbFileSizes defaultExpectedDbFileSizes () {
205+ return new DbFileSizes (EXPECTED_TRIPLES_DATA_SIZE_BYTES , EXPECTED_VALUES_DATA_SIZE_BYTES );
206+ }
207+
208+ private DbFileSizes currentDbFileSizes () {
209+ return new DbFileSizes (dbFileSize (TRIPLES_DATA_FILE ), dbFileSize (VALUES_DATA_FILE ));
210+ }
211+
212+ private boolean hasExpectedDbFileSizes (DbFileSizes expectedDbFileSizes ) {
213+ var currentDbFileSizes = currentDbFileSizes ();
214+ return currentDbFileSizes .triplesDataSizeBytes == expectedDbFileSizes .triplesDataSizeBytes
215+ && currentDbFileSizes .valuesDataSizeBytes == expectedDbFileSizes .valuesDataSizeBytes ;
216+ }
217+
218+ private File expectedDbFileSizeFile () {
219+ return new File (STORE_DIRECTORY , EXPECTED_DB_FILE_SIZES_FILE );
148220 }
149221
150222 private long dbFileSize (String relativePath ) {
@@ -261,10 +333,27 @@ public void setupVerifiesExpectedDbFileSizesInFixedStore() throws IOException {
261333 z_queryIndex = 0 ;
262334 setup ();
263335 try {
264- assertEquals (EXPECTED_TRIPLES_DATA_SIZE_BYTES , dbFileSize (TRIPLES_DATA_FILE ),
336+ var expectedDbFileSizes = readExpectedDbFileSizes ();
337+ assertEquals (expectedDbFileSizes .triplesDataSizeBytes , dbFileSize (TRIPLES_DATA_FILE ),
265338 "Unexpected byte size for " + TRIPLES_DATA_FILE );
266- assertEquals (EXPECTED_VALUES_DATA_SIZE_BYTES , dbFileSize (VALUES_DATA_FILE ),
339+ assertEquals (expectedDbFileSizes . valuesDataSizeBytes , dbFileSize (VALUES_DATA_FILE ),
267340 "Unexpected byte size for " + VALUES_DATA_FILE );
341+ assertTrue (expectedDbFileSizeFile ().isFile (),
342+ "Expected sidecar file to exist: " + expectedDbFileSizeFile ());
343+ } finally {
344+ tearDown ();
345+ }
346+ }
347+
348+ @ Test
349+ public void executeQueryReturnsExpectedCountForPharmaQueryTenAfterFreshGeneration () throws IOException {
350+ FileUtils .deleteDirectory (STORE_DIRECTORY );
351+ themeName = "PHARMA" ;
352+ z_queryIndex = 10 ;
353+ setup ();
354+ try {
355+ assertEquals (ThemeQueryCatalog .expectedCountFor (theme , z_queryIndex ), executeQuery (),
356+ "Unexpected count for freshly generated PHARMA query index 10" );
268357 } finally {
269358 tearDown ();
270359 }
@@ -305,4 +394,14 @@ private static String[] paramValues(String fieldName) {
305394 }
306395 }
307396
397+ private static final class DbFileSizes {
398+ private final long triplesDataSizeBytes ;
399+ private final long valuesDataSizeBytes ;
400+
401+ private DbFileSizes (long triplesDataSizeBytes , long valuesDataSizeBytes ) {
402+ this .triplesDataSizeBytes = triplesDataSizeBytes ;
403+ this .valuesDataSizeBytes = valuesDataSizeBytes ;
404+ }
405+ }
406+
308407}
0 commit comments