use of org.neo4j.kernel.impl.transaction.state.storeview.PropertyAwareEntityStoreScan.CursorEntityIdIterator in project neo4j by neo4j.
the class StoreScanStageTest method shouldGenerateUpdatesInParallel.
@ValueSource(booleans = { true, false })
@ParameterizedTest(name = "parallelWrite={0}")
void shouldGenerateUpdatesInParallel(boolean parallelWrite) {
// given
StubStorageCursors data = someData();
EntityIdIterator entityIdIterator = new CursorEntityIdIterator<>(data.allocateNodeCursor(NULL));
var propertyConsumer = new ThreadCapturingPropertyConsumer();
var tokenConsumer = new ThreadCapturingTokenConsumer();
ControlledLockFunction lockFunction = new ControlledLockFunction();
StoreScanStage<StorageNodeCursor> scan = new StoreScanStage<>(dbConfig, config, ct -> entityIdIterator, NO_EXTERNAL_UPDATES, new AtomicBoolean(true), data, new int[] { LABEL }, alwaysTrue(), propertyConsumer, tokenConsumer, new NodeCursorBehaviour(data), lockFunction, parallelWrite, jobScheduler, PageCacheTracer.NULL, EmptyMemoryTracker.INSTANCE);
// when
runScan(scan);
// then it completes and we see > 1 threads
assertThat(lockFunction.seenThreads.size()).isGreaterThan(1);
if (parallelWrite) {
assertThat(propertyConsumer.seenThreads.size()).isGreaterThan(1);
assertThat(tokenConsumer.seenThreads.size()).isGreaterThan(1);
} else {
assertThat(propertyConsumer.seenThreads.size()).isEqualTo(1);
assertThat(tokenConsumer.seenThreads.size()).isEqualTo(1);
}
}
use of org.neo4j.kernel.impl.transaction.state.storeview.PropertyAwareEntityStoreScan.CursorEntityIdIterator in project neo4j by neo4j.
the class StoreScanStageTest method shouldPanicAndExitStageOnWriteFailure.
@Test
void shouldPanicAndExitStageOnWriteFailure() {
// given
StubStorageCursors data = someData();
EntityIdIterator entityIdIterator = new CursorEntityIdIterator<>(data.allocateNodeCursor(NULL));
var failingWriter = new PropertyConsumer(() -> {
throw new IllegalStateException("Failed to write");
});
StoreScanStage<StorageNodeCursor> scan = new StoreScanStage<>(dbConfig, config, ct -> entityIdIterator, NO_EXTERNAL_UPDATES, new AtomicBoolean(true), data, new int[] { LABEL }, alwaysTrue(), failingWriter, null, new NodeCursorBehaviour(data), id -> null, true, jobScheduler, PageCacheTracer.NULL, EmptyMemoryTracker.INSTANCE);
// when/then
assertThatThrownBy(() -> runScan(scan)).isInstanceOf(IllegalStateException.class).hasMessageContaining("Failed to write");
}
use of org.neo4j.kernel.impl.transaction.state.storeview.PropertyAwareEntityStoreScan.CursorEntityIdIterator in project neo4j by neo4j.
the class StoreScanStageTest method shouldReportCorrectNumberOfEntitiesProcessed.
@Test
void shouldReportCorrectNumberOfEntitiesProcessed() {
// given
StubStorageCursors data = someData();
AtomicReference<StoreScanStage<StorageNodeCursor>> stage = new AtomicReference<>();
EntityIdIterator entityIdIterator = new CursorEntityIdIterator<>(data.allocateNodeCursor(NULL)) {
private long manualCounter;
@Override
protected boolean fetchNext() {
assertThat(stage.get().numberOfIteratedEntities()).isEqualTo((manualCounter / config.batchSize()) * config.batchSize());
manualCounter++;
return super.fetchNext();
}
};
StoreScanStage<StorageNodeCursor> scan = new StoreScanStage(dbConfig, config, ct -> entityIdIterator, NO_EXTERNAL_UPDATES, new AtomicBoolean(true), data, new int[] { LABEL }, alwaysTrue(), new ThreadCapturingPropertyConsumer(), new ThreadCapturingTokenConsumer(), new NodeCursorBehaviour(data), l -> LockService.NO_LOCK, true, jobScheduler, PageCacheTracer.NULL, EmptyMemoryTracker.INSTANCE);
stage.set(scan);
// when
runScan(scan);
// then
assertThat(scan.numberOfIteratedEntities()).isEqualTo((long) config.batchSize() * NUMBER_OF_BATCHES);
}
use of org.neo4j.kernel.impl.transaction.state.storeview.PropertyAwareEntityStoreScan.CursorEntityIdIterator in project neo4j by neo4j.
the class StoreScanStageTest method shouldAbortScanOnStopped.
@Test
void shouldAbortScanOnStopped() {
// given
StubStorageCursors data = someData();
EntityIdIterator entityIdIterator = new CursorEntityIdIterator<>(data.allocateNodeCursor(NULL));
AtomicInteger numBatchesProcessed = new AtomicInteger();
AtomicBoolean continueScanning = new AtomicBoolean(true);
AbortingExternalUpdatesCheck externalUpdatesCheck = new AbortingExternalUpdatesCheck(1, continueScanning);
var writer = new PropertyConsumer(() -> numBatchesProcessed.incrementAndGet());
StoreScanStage<StorageNodeCursor> scan = new StoreScanStage(dbConfig, config, ct -> entityIdIterator, externalUpdatesCheck, continueScanning, data, new int[] { LABEL }, alwaysTrue(), writer, null, new NodeCursorBehaviour(data), id -> null, true, jobScheduler, PageCacheTracer.NULL, EmptyMemoryTracker.INSTANCE);
// when
runScan(scan);
// then
assertThat(numBatchesProcessed.get()).isEqualTo(2);
}
use of org.neo4j.kernel.impl.transaction.state.storeview.PropertyAwareEntityStoreScan.CursorEntityIdIterator in project neo4j by neo4j.
the class StoreScanStageTest method shouldApplyExternalUpdatesIfThereAreSuch.
@Test
void shouldApplyExternalUpdatesIfThereAreSuch() {
// given
StubStorageCursors data = someData();
EntityIdIterator entityIdIterator = new CursorEntityIdIterator<>(data.allocateNodeCursor(NULL));
AtomicInteger numBatchesProcessed = new AtomicInteger();
ControlledExternalUpdatesCheck externalUpdatesCheck = new ControlledExternalUpdatesCheck(config.batchSize(), 2, numBatchesProcessed);
var writer = new PropertyConsumer(() -> numBatchesProcessed.incrementAndGet());
StoreScanStage<StorageNodeCursor> scan = new StoreScanStage(dbConfig, config, ct -> entityIdIterator, externalUpdatesCheck, new AtomicBoolean(true), data, new int[] { LABEL }, alwaysTrue(), writer, null, new NodeCursorBehaviour(data), id -> null, true, jobScheduler, PageCacheTracer.NULL, EmptyMemoryTracker.INSTANCE);
// when
runScan(scan);
// then
assertThat(externalUpdatesCheck.applyCallCount).isEqualTo(1);
}
Aggregations