|
55 | 55 | import org.eclipse.rdf4j.sail.SailException; |
56 | 56 | import org.eclipse.rdf4j.sail.base.SailDataset; |
57 | 57 | import org.eclipse.rdf4j.sail.base.SailSink; |
| 58 | +import org.eclipse.rdf4j.sail.base.SketchBasedJoinEstimator; |
58 | 59 | import org.eclipse.rdf4j.sail.lmdb.config.LmdbStoreConfig; |
59 | 60 | import org.junit.jupiter.api.AfterEach; |
60 | 61 | import org.junit.jupiter.api.BeforeEach; |
@@ -412,6 +413,51 @@ void approveAllUsesConfiguredBulkOperationSize() throws Exception { |
412 | 413 | } |
413 | 414 | } |
414 | 415 |
|
| 416 | + @Test |
| 417 | + void approveAllBulkFailureDiscardsNonIsolatedEstimatorUpdates() throws Exception { |
| 418 | + LmdbStoreConfig config = new LmdbStoreConfig("spoc,posc"); |
| 419 | + setBulkOperationSize(config, 2); |
| 420 | + LmdbStore sail = new LmdbStore(new File(dataDir, "bulk-failure-estimator"), config); |
| 421 | + sail.init(); |
| 422 | + |
| 423 | + try { |
| 424 | + LmdbSailStore backingStore = sail.getBackingStore(); |
| 425 | + backingStore.enableMultiThreading = false; |
| 426 | + SketchBasedJoinEstimator estimator = backingStore.getSketchBasedJoinEstimator(); |
| 427 | + try (SailSink seedSink = backingStore.getExplicitSailSource().sink(IsolationLevels.NONE)) { |
| 428 | + seedSink.approveAll(sampleStatements(5), Set.of()); |
| 429 | + seedSink.flush(); |
| 430 | + } |
| 431 | + estimator.rebuild(); |
| 432 | + assertTrue("Expected estimator to be ready before the failed bulk add", estimator.isReady()); |
| 433 | + |
| 434 | + Field tripleStoreField = LmdbSailStore.class.getDeclaredField("tripleStore"); |
| 435 | + tripleStoreField.setAccessible(true); |
| 436 | + TripleStore originalTripleStore = (TripleStore) tripleStoreField.get(backingStore); |
| 437 | + TripleStore tripleStoreSpy = spy(originalTripleStore); |
| 438 | + |
| 439 | + doAnswer(invocation -> { |
| 440 | + IntConsumer addedIndexConsumer = invocation.getArgument(6); |
| 441 | + addedIndexConsumer.accept(0); |
| 442 | + throw new IOException("expected aligned bulk failure after estimator update"); |
| 443 | + }).when(tripleStoreSpy) |
| 444 | + .storeTriplesAligned(any(long[].class), any(long[].class), any(long[].class), |
| 445 | + any(long[].class), anyInt(), anyBoolean(), any(IntConsumer.class)); |
| 446 | + |
| 447 | + tripleStoreField.set(backingStore, tripleStoreSpy); |
| 448 | + try (SailSink sink = backingStore.getExplicitSailSource().sink(IsolationLevels.NONE)) { |
| 449 | + assertThrows(SailException.class, () -> sink.approveAll(sampleStatements(2), Set.of())); |
| 450 | + |
| 451 | + assertFalse("Expected rollback to discard estimator state after an eager non-isolated update", |
| 452 | + estimator.isReady()); |
| 453 | + } finally { |
| 454 | + tripleStoreField.set(backingStore, originalTripleStore); |
| 455 | + } |
| 456 | + } finally { |
| 457 | + sail.shutDown(); |
| 458 | + } |
| 459 | + } |
| 460 | + |
415 | 461 | private static void setBulkOperationSize(LmdbStoreConfig config, int bulkOperationSize) { |
416 | 462 | try { |
417 | 463 | Method setter = config.getClass().getMethod("setBulkOperationSize", int.class); |
|
0 commit comments