Search in sources :

Example 86 with CursorContext

use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.

the class MuninnPageCacheTest method mustFlushDirtyPagesOnEvictingLastPage.

@Test
void mustFlushDirtyPagesOnEvictingLastPage() throws Exception {
    writeInitialDataTo(file("a"));
    RecordingPageCacheTracer tracer = new RecordingPageCacheTracer();
    RecordingPageCursorTracer cursorContext = new RecordingPageCursorTracer(tracer, "mustFlushDirtyPagesOnEvictingLastPage");
    try (MuninnPageCache pageCache = createPageCache(fs, 2, blockCacheFlush(tracer));
        PagedFile pagedFile = map(pageCache, file("a"), 8)) {
        try (PageCursor cursor = pagedFile.io(1, PF_SHARED_WRITE_LOCK, new CursorContext(cursorContext))) {
            assertTrue(cursor.next());
            cursor.putLong(0L);
        }
        cursorContext.reportEvents();
        assertNotNull(cursorContext.observe(Fault.class));
        assertEquals(1, cursorContext.faults());
        assertEquals(1, tracer.faults());
        long clockArm = pageCache.evictPages(1, 0, tracer.beginPageEvictions(1));
        assertThat(clockArm).isEqualTo(1L);
        assertNotNull(tracer.observe(Evict.class));
        ByteBuffer buf = readIntoBuffer("a");
        assertThat(buf.getLong()).isEqualTo(x);
        assertThat(buf.getLong()).isEqualTo(0L);
    }
}
Also used : PagedFile(org.neo4j.io.pagecache.PagedFile) RecordingPageCacheTracer(org.neo4j.io.pagecache.tracing.recording.RecordingPageCacheTracer) Fault(org.neo4j.io.pagecache.tracing.recording.RecordingPageCursorTracer.Fault) Evict(org.neo4j.io.pagecache.tracing.recording.RecordingPageCacheTracer.Evict) CursorContext(org.neo4j.io.pagecache.context.CursorContext) RecordingPageCursorTracer(org.neo4j.io.pagecache.tracing.recording.RecordingPageCursorTracer) ByteBuffer(java.nio.ByteBuffer) PageCursor(org.neo4j.io.pagecache.PageCursor) PageCacheTest(org.neo4j.io.pagecache.PageCacheTest) Test(org.junit.jupiter.api.Test)

Example 87 with CursorContext

use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.

the class PageCacheTest method tracerMustBeNotifiedAboutPinUnpinFaultFlushAndEvictionEventsWhenWriting.

@Test
void tracerMustBeNotifiedAboutPinUnpinFaultFlushAndEvictionEventsWhenWriting() {
    assertTimeoutPreemptively(ofMillis(SHORT_TIMEOUT_MILLIS), () -> {
        long pagesToGenerate = 142;
        DefaultPageCacheTracer tracer = new DefaultPageCacheTracer();
        getPageCache(fs, maxPages, tracer);
        long initialPins = tracer.pins();
        long initialUnpins = tracer.unpins();
        try (CursorContext cursorContext = new CursorContext(tracer.createPageCursorTracer("tracerMustBeNotifiedAboutPinUnpinFaultFlushAndEvictionEventsWhenWriting"));
            PagedFile pagedFile = map(file("a"), filePageSize);
            PageCursor cursor = pagedFile.io(0, PF_SHARED_WRITE_LOCK, cursorContext)) {
            for (long i = 0; i < pagesToGenerate; i++) {
                assertTrue(cursor.next());
                assertThat(cursor.getCurrentPageId()).isEqualTo(i);
                // This does not count as a pin
                assertTrue(cursor.next(i));
                assertThat(cursor.getCurrentPageId()).isEqualTo(i);
                writeRecords(cursor);
            }
            // This counts as a single pin
            assertTrue(cursor.next(0));
            assertTrue(cursor.next(0));
        }
        assertThat(tracer.pins()).as("wrong count of pins").isEqualTo(pagesToGenerate + 1 + initialPins);
        assertThat(tracer.unpins()).as("wrong count of unpins").isEqualTo(pagesToGenerate + 1 + initialUnpins);
        // We might be unlucky and fault in the second next call, on the page
        // we brought up in the first next call. That's why we assert that we
        // have observed *at least* the countedPages number of faults.
        long faults = tracer.faults();
        assertThat(faults).as("wrong count of faults").isGreaterThanOrEqualTo(pagesToGenerate);
        // Every page we move forward can put the freelist behind so the cache
        // wants to evict more pages. Plus, every page fault we do could also
        // block and get a page directly transferred to it, and these kinds of
        // evictions can count in addition to the evictions we do when the
        // cache is behind on keeping the freelist full.
        assertThat(tracer.evictions()).as("wrong count of evictions").isGreaterThanOrEqualTo(pagesToGenerate - maxPages).isLessThanOrEqualTo(pagesToGenerate + faults);
        // We use greaterThanOrEqualTo because we visit each page twice, and
        // that leaves a small window wherein we can race with eviction, have
        // the evictor flush the page, and then fault it back and mark it as
        // dirty again.
        // We also subtract 'maxPages' from the expected flush count, because
        // vectored IO may coalesce all the flushes we do as part of unmapping
        // the file, into a single flush.
        long flushes = tracer.flushes();
        long bytesWritten = tracer.bytesWritten();
        assertThat(flushes).as("wrong count of flushes").isGreaterThanOrEqualTo(pagesToGenerate - maxPages);
        assertThat(bytesWritten).as("wrong count of bytes written").isGreaterThanOrEqualTo(pagesToGenerate * filePageSize);
    });
}
Also used : CursorContext(org.neo4j.io.pagecache.context.CursorContext) DefaultPageCacheTracer(org.neo4j.io.pagecache.tracing.DefaultPageCacheTracer) RepeatedTest(org.junit.jupiter.api.RepeatedTest) Test(org.junit.jupiter.api.Test)

Example 88 with CursorContext

use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.

the class PageCacheTest method restartByShouldRetryMustCarryOverExistingPin.

@Test
void restartByShouldRetryMustCarryOverExistingPin() throws IOException {
    DefaultPageCacheTracer tracer = new DefaultPageCacheTracer();
    getPageCache(fs, maxPages, tracer);
    generateFileWithRecords(file("a"), recordCount, recordSize);
    try (PagedFile pagedFile = map(file("a"), filePageSize);
        CursorContext cursorContext = new CursorContext(tracer.createPageCursorTracer("test"))) {
        try (PageCursor reader = pagedFile.io(0, PF_SHARED_READ_LOCK, cursorContext)) {
            assertTrue(reader.next());
            // Cause the page under the reader cursor to be evicted.
            try (PagedFile otherPagedFile = map(existingFile("b"), filePageSize);
                PageCursor writer = otherPagedFile.io(0, PF_SHARED_WRITE_LOCK, cursorContext)) {
                while (!reader.shouldRetry()) {
                    for (int i = 0; i < maxPages * 10; i++) {
                        assertTrue(writer.next(i));
                    }
                }
            }
        }
    }
    // Then we should see pins and unpins pair up exactly.
    assertThat(tracer.unpins()).isEqualTo(tracer.pins());
}
Also used : CursorContext(org.neo4j.io.pagecache.context.CursorContext) DefaultPageCacheTracer(org.neo4j.io.pagecache.tracing.DefaultPageCacheTracer) RepeatedTest(org.junit.jupiter.api.RepeatedTest) Test(org.junit.jupiter.api.Test)

Example 89 with CursorContext

use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.

the class PageCacheTest method tracerMustBeNotifiedOfReadAndWritePins.

@Test
void tracerMustBeNotifiedOfReadAndWritePins() throws Exception {
    final AtomicInteger writeCount = new AtomicInteger();
    final AtomicInteger readCount = new AtomicInteger();
    DefaultPageCacheTracer tracer = new DefaultPageCacheTracer();
    DefaultPageCursorTracer pageCursorTracer = new DefaultPageCursorTracer(tracer, "test") {

        @Override
        public PinEvent beginPin(boolean writeLock, long filePageId, PageSwapper swapper) {
            (writeLock ? writeCount : readCount).getAndIncrement();
            return super.beginPin(writeLock, filePageId, swapper);
        }
    };
    getPageCache(fs, maxPages, tracer);
    generateFileWithRecords(file("a"), recordCount, recordSize);
    int pinsForRead = 13;
    int pinsForWrite = 42;
    try (PagedFile pagedFile = map(file("a"), filePageSize)) {
        try (PageCursor cursor = pagedFile.io(0, PF_SHARED_READ_LOCK, new CursorContext(pageCursorTracer))) {
            for (int i = 0; i < pinsForRead; i++) {
                assertTrue(cursor.next());
            }
        }
        dirtyManyPages(pagedFile, pinsForWrite, new CursorContext(pageCursorTracer));
    }
    assertThat(readCount.get()).as("wrong read pin count").isEqualTo(pinsForRead);
    assertThat(writeCount.get()).as("wrong write pin count").isEqualTo(pinsForWrite);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DefaultPageCursorTracer(org.neo4j.io.pagecache.tracing.cursor.DefaultPageCursorTracer) CursorContext(org.neo4j.io.pagecache.context.CursorContext) DefaultPageCacheTracer(org.neo4j.io.pagecache.tracing.DefaultPageCacheTracer) RepeatedTest(org.junit.jupiter.api.RepeatedTest) Test(org.junit.jupiter.api.Test)

Example 90 with CursorContext

use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.

the class MuninnPageCacheTest method ableToEvictAllPageInAPageCache.

@Test
void ableToEvictAllPageInAPageCache() throws IOException {
    writeInitialDataTo(file("a"));
    RecordingPageCacheTracer tracer = new RecordingPageCacheTracer();
    RecordingPageCursorTracer cursorContext = new RecordingPageCursorTracer(tracer, "ableToEvictAllPageInAPageCache");
    try (MuninnPageCache pageCache = createPageCache(fs, 2, blockCacheFlush(tracer));
        PagedFile pagedFile = map(pageCache, file("a"), 8);
        CursorContext context = new CursorContext(cursorContext)) {
        try (PageCursor cursor = pagedFile.io(0, PF_SHARED_READ_LOCK, context)) {
            assertTrue(cursor.next());
        }
        try (PageCursor cursor = pagedFile.io(1, PF_SHARED_READ_LOCK, context)) {
            assertTrue(cursor.next());
        }
        evictAllPages(pageCache);
    }
}
Also used : PagedFile(org.neo4j.io.pagecache.PagedFile) RecordingPageCacheTracer(org.neo4j.io.pagecache.tracing.recording.RecordingPageCacheTracer) CursorContext(org.neo4j.io.pagecache.context.CursorContext) RecordingPageCursorTracer(org.neo4j.io.pagecache.tracing.recording.RecordingPageCursorTracer) PageCursor(org.neo4j.io.pagecache.PageCursor) PageCacheTest(org.neo4j.io.pagecache.PageCacheTest) Test(org.junit.jupiter.api.Test)

Aggregations

CursorContext (org.neo4j.io.pagecache.context.CursorContext)161 Test (org.junit.jupiter.api.Test)74 DefaultPageCacheTracer (org.neo4j.io.pagecache.tracing.DefaultPageCacheTracer)52 PageCursor (org.neo4j.io.pagecache.PageCursor)40 IOException (java.io.IOException)31 UncheckedIOException (java.io.UncheckedIOException)27 PageCursorTracer (org.neo4j.io.pagecache.tracing.cursor.PageCursorTracer)27 Path (java.nio.file.Path)17 PagedFile (org.neo4j.io.pagecache.PagedFile)17 ArrayList (java.util.ArrayList)16 PageCacheTest (org.neo4j.io.pagecache.PageCacheTest)15 MutableLong (org.apache.commons.lang3.mutable.MutableLong)13 MemoryTracker (org.neo4j.memory.MemoryTracker)12 PageCache (org.neo4j.io.pagecache.PageCache)11 ProgressListener (org.neo4j.internal.helpers.progress.ProgressListener)10 DynamicRecord (org.neo4j.kernel.impl.store.record.DynamicRecord)10 List (java.util.List)9 RepeatedTest (org.junit.jupiter.api.RepeatedTest)9 NodeRecord (org.neo4j.kernel.impl.store.record.NodeRecord)9 PageCacheTracer (org.neo4j.io.pagecache.tracing.PageCacheTracer)8