@Test(timeout = 1000) public void readers_and_writers_must_block_on_evicting_page() throws Exception { // If we have a loaded page ... PageSwapper io = new BufferPageSwapper(ByteBuffer.allocate(TEST_PAGE_SIZE)); long pageId = 12; PinnablePage page = table.load(io, pageId, PageLock.EXCLUSIVE); monitor.observe(Fault.class); // ... a page that will take a long time to evict CountDownLatch latch = monitor.trap(is(new Evict(io, pageId))); // ... and a page that is soon up for eviction page.unpin(PageLock.EXCLUSIVE); // ... then when we observe the eviction taking place monitor.observe(Evict.class); // ... other threads should not be able to pin that page Thread pinForShared = fork($pinUnpin(page, io, pageId, PageLock.SHARED)); Thread pinForExclusive = fork($pinUnpin(page, io, pageId, PageLock.EXCLUSIVE)); awaitThreadState(pinForShared, Thread.State.WAITING); awaitThreadState(pinForExclusive, Thread.State.WAITING); // ... until the eviction finishes latch.countDown(); pinForShared.join(); pinForExclusive.join(); }
@Test public void must_notify_monitor_of_evicted_pages() throws Exception { // If we load a page ... PageSwapper io = new BufferPageSwapper(ByteBuffer.allocate(TEST_PAGE_SIZE)); long pageId = 12; PinnablePage page = table.load(io, pageId, PageLock.EXCLUSIVE); page.unpin(PageLock.EXCLUSIVE); // ... then we should observe its page fault assertThat(monitor.observe(Fault.class), is(new Fault(io, pageId))); // ... and when it sits idle for long enough, we should observe its eviction assertThat(monitor.observe(Evict.class), is(new Evict(io, pageId))); }
@Test public void flushing_pages_with_specific_pageio_must_not_race_with_eviction() throws Exception { // The idea is that we repeatedly load a page with an EXCLUSIVE lock, and unpin it so it can // be evicted. As soon as we have unpinned, we repeatedly try to flush it with our given // PageIO. If this causes an exception to be thrown, then we've raced with the eviction // where we shouldn't. PageSwapper io = new BufferPageSwapper(ByteBuffer.allocate(TEST_PAGE_SIZE)); long pageId = 12; PinnablePage page = table.load(io, pageId, PageLock.EXCLUSIVE); monitor.observe(Fault.class); page.unpin(PageLock.EXCLUSIVE); // eviction is now possible LockSupport.unpark(sweeperThread); while (monitor.tryObserve(Evict.class) == null) { table.flush(io); } }