use of org.neo4j.io.pagecache.PageSwapperFactory in project neo4j by neo4j.
the class RandomPageCacheTestHarness method runIteration.
@SuppressWarnings("unchecked")
private void runIteration(long timeout, TimeUnit unit) throws Exception {
assert filePageSize % recordFormat.getRecordSize() == 0 : "File page size must be a multiple of the record size";
if (!fixedRandomSeed) {
randomSeed = ThreadLocalRandom.current().nextLong();
}
FileSystemAbstraction fs = this.fs;
Path[] files = buildFileNames();
RandomAdversary adversary = new RandomAdversary(mischiefRate, failureRate, errorRate);
adversary.setProbabilityFactor(0.0);
if (useAdversarialIO) {
adversary.setSeed(randomSeed);
fs = new AdversarialFileSystemAbstraction(adversary, fs);
}
PageSwapperFactory swapperFactory = new SingleFilePageSwapperFactory(fs);
JobScheduler jobScheduler = new ThreadPoolJobScheduler();
MuninnPageCache cache = new MuninnPageCache(swapperFactory, jobScheduler, MuninnPageCache.config(cachePageCount).pageCacheTracer(tracer));
if (filePageSize == 0) {
filePageSize = cache.pageSize();
}
cache.setPrintExceptionsOnClose(false);
Map<Path, PagedFile> fileMap = new HashMap<>(files.length);
for (int i = 0; i < Math.min(files.length, initialMappedFiles); i++) {
Path file = files[i];
fileMap.put(file, cache.map(file, filePageSize, DEFAULT_DATABASE_NAME));
}
plan = plan(cache, files, fileMap);
AtomicBoolean stopSignal = new AtomicBoolean();
Callable<Void> planRunner = new PlanRunner(plan, stopSignal, profiler);
Future<Void>[] futures = new Future[concurrencyLevel];
for (int i = 0; i < concurrencyLevel; i++) {
futures[i] = executorService.submit(planRunner);
}
if (preparation != null) {
preparation.run(cache, this.fs, plan.getFilesTouched());
}
adversary.setProbabilityFactor(1.0);
plan.start();
long deadlineMillis = System.currentTimeMillis() + unit.toMillis(timeout);
long now;
try {
for (Future<Void> future : futures) {
now = System.currentTimeMillis();
if (deadlineMillis < now) {
throw new TimeoutException();
}
future.get(deadlineMillis - now, TimeUnit.MILLISECONDS);
}
adversary.setProbabilityFactor(0.0);
runVerificationPhase(cache);
} finally {
stopSignal.set(true);
adversary.setProbabilityFactor(0.0);
try {
for (Future<Void> future : futures) {
future.get(10, TimeUnit.SECONDS);
}
} catch (InterruptedException | TimeoutException e) {
for (Future<Void> future : futures) {
future.cancel(true);
}
throw new RuntimeException(e);
}
try {
plan.close();
cache.close();
jobScheduler.close();
if (this.fs instanceof EphemeralFileSystemAbstraction) {
this.fs.close();
this.fs = new EphemeralFileSystemAbstraction();
} else {
for (Path file : files) {
Files.delete(file);
}
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
use of org.neo4j.io.pagecache.PageSwapperFactory in project neo4j by neo4j.
the class SingleFilePageSwapperTest method doNotReportExternalIoOnCheckpointerCalledVectoredFlush.
@Test
void doNotReportExternalIoOnCheckpointerCalledVectoredFlush() throws IOException {
createEmptyFile();
PageSwapperFactory factory = createSwapperFactory(getFs());
CountingIOController controller = new CountingIOController();
try (var swapper = createSwapper(factory, getPath(), 4, null, false, false, true, controller)) {
long target1 = createPage(4);
long target2 = createPage(4);
long target3 = createPage(4);
int numberOfReads = 12;
int buffers = 3;
for (int i = 0; i < numberOfReads; i++) {
assertEquals(12, swapper.write(0, new long[] { target1, target2, target3 }, new int[] { 4, 4, 4 }, buffers, buffers));
}
assertEquals(0, controller.getExternalIOCounter());
}
}
use of org.neo4j.io.pagecache.PageSwapperFactory in project neo4j by neo4j.
the class SingleFilePageSwapperTest method uninterruptibleWrite.
@Test
void uninterruptibleWrite() throws Exception {
byte[] pageContent = new byte[] { 1, 2, 3, 4 };
StoreChannel channel = getFs().write(getPath());
channel.writeAll(wrap(pageContent));
channel.close();
PageSwapperFactory factory = createSwapperFactory(getFs());
PageSwapper swapper = createSwapper(factory, getPath(), 4, null, false);
long target = createPage(4);
CountDownLatch startInterruptsLatch = new CountDownLatch(1);
AtomicBoolean writeFlag = new AtomicBoolean(true);
var uninterruptibleFuture = operationExecutor.submit(() -> {
startInterruptsLatch.countDown();
while (writeFlag.get()) {
try {
swapper.write(0, target);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
});
startInterruptsLatch.await();
assertFalse(threadRegistryFactory.getThreads().isEmpty());
for (int i = 0; i < INTERRUPT_ATTEMPTS; i++) {
threadRegistryFactory.getThreads().forEach(Thread::interrupt);
parkNanos(MILLISECONDS.toNanos(10));
}
writeFlag.set(false);
assertDoesNotThrow((ThrowingSupplier<?>) uninterruptibleFuture::get);
}
use of org.neo4j.io.pagecache.PageSwapperFactory in project neo4j by neo4j.
the class SingleFilePageSwapperTest method reportExternalIoOnSwapOutWithLength.
@Test
void reportExternalIoOnSwapOutWithLength() throws IOException {
createEmptyFile();
PageSwapperFactory factory = createSwapperFactory(getFs());
CountingIOController controller = new CountingIOController();
try (var swapper = createSwapper(factory, getPath(), 4, null, false, false, true, controller)) {
long target = createPage(4);
int numberOfWrites = 42;
for (int i = 0; i < numberOfWrites; i++) {
assertEquals(4, swapper.write(0, target, 4));
}
assertEquals(numberOfWrites, controller.getExternalIOCounter());
}
}
use of org.neo4j.io.pagecache.PageSwapperFactory in project neo4j by neo4j.
the class SingleFilePageSwapperTest method mustZeroFillPageBeyondEndOfFile.
@Test
void mustZeroFillPageBeyondEndOfFile() throws Exception {
byte[] bytes = new byte[] { // --- page 0:
1, 2, 3, 4, // --- page 1:
5, 6 };
StoreChannel channel = getFs().write(getPath());
channel.writeAll(wrap(bytes));
channel.close();
PageSwapperFactory factory = createSwapperFactory(getFs());
PageSwapper swapper = createSwapper(factory, getPath(), 4, null, false);
long target = createPage(4);
assertEquals(2, swapper.read(1, target));
assertThat(array(target)).containsExactly(5, 6, 0, 0);
}
Aggregations