@Test public void testMultiThreads() throws IOException { mappedPageFactory = new MappedPageFactoryImpl(1024 * 1024 * 128, testDir + "/test_multi_threads", 2 * 1000); int pageNumLimit = 200; int threadNum = 1000; Map<Integer, IMappedPage[]> sharedMap1 = this.testAndGetSharedMap(mappedPageFactory, threadNum, pageNumLimit); assertTrue(this.mappedPageFactory.getCacheSize() == pageNumLimit); Map<Integer, IMappedPage[]> sharedMap2 = this.testAndGetSharedMap(mappedPageFactory, threadNum, pageNumLimit); assertTrue(this.mappedPageFactory.getCacheSize() == pageNumLimit); // pages in two maps should be same since they are all cached verifyMap(sharedMap1, sharedMap2, threadNum, pageNumLimit, true); verifyClosed(sharedMap1, threadNum, pageNumLimit, false); TestUtil.sleepQuietly(2500); this.mappedPageFactory.acquirePage(pageNumLimit + 1); // trigger mark&sweep assertTrue(this.mappedPageFactory.getCacheSize() == 1); Map<Integer, IMappedPage[]> sharedMap3 = this.testAndGetSharedMap(mappedPageFactory, threadNum, pageNumLimit); assertTrue(this.mappedPageFactory.getCacheSize() == pageNumLimit + 1); // pages in two maps should be different since all pages in sharedMap1 has expired and purged // out verifyMap(sharedMap1, sharedMap3, threadNum, pageNumLimit, false); verifyClosed(sharedMap3, threadNum, pageNumLimit, false); verifyClosed(sharedMap1, threadNum, pageNumLimit, true); // ensure no memory leak assertTrue(((MappedPageFactoryImpl) mappedPageFactory).getLockMapSize() == 0); }
@Test public void testSingleThread() throws IOException { mappedPageFactory = new MappedPageFactoryImpl(1024 * 1024 * 128, testDir + "/test_single_thread", 2 * 1000); IMappedPage mappedPage = mappedPageFactory.acquirePage(0); // first acquire assertNotNull(mappedPage); IMappedPage mappedPage0 = mappedPageFactory.acquirePage(0); // second acquire assertSame(mappedPage, mappedPage0); IMappedPage mappedPage1 = mappedPageFactory.acquirePage(1); assertNotSame(mappedPage0, mappedPage1); mappedPageFactory.releasePage(0); // release first acquire mappedPageFactory.releasePage(0); // release second acquire TestUtil.sleepQuietly(2200); // let page0 expire mappedPageFactory.acquirePage(2); // trigger mark&sweep and purge old page0 mappedPage = mappedPageFactory.acquirePage(0); // create a new page0 assertNotSame(mappedPage, mappedPage0); TestUtil.sleepQuietly(1000); // let the async cleaner do the job assertTrue(!mappedPage.isClosed()); assertTrue(mappedPage0.isClosed()); for (long i = 0; i < 100; i++) { assertNotNull(mappedPageFactory.acquirePage(i)); } assertTrue(mappedPageFactory.getCacheSize() == 100); Set<Long> indexSet = mappedPageFactory.getExistingBackFileIndexSet(); assertTrue(indexSet.size() == 100); for (long i = 0; i < 100; i++) { assertTrue(indexSet.contains(i)); } this.mappedPageFactory.deletePage(0); assertTrue(mappedPageFactory.getCacheSize() == 99); indexSet = mappedPageFactory.getExistingBackFileIndexSet(); assertTrue(indexSet.size() == 99); this.mappedPageFactory.deletePage(1); assertTrue(mappedPageFactory.getCacheSize() == 98); indexSet = mappedPageFactory.getExistingBackFileIndexSet(); assertTrue(indexSet.size() == 98); for (long i = 2; i < 50; i++) { this.mappedPageFactory.deletePage(i); } assertTrue(mappedPageFactory.getCacheSize() == 50); indexSet = mappedPageFactory.getExistingBackFileIndexSet(); assertTrue(indexSet.size() == 50); this.mappedPageFactory.deleteAllPages(); assertTrue(mappedPageFactory.getCacheSize() == 0); indexSet = mappedPageFactory.getExistingBackFileIndexSet(); assertTrue(indexSet.size() == 0); long start = System.currentTimeMillis(); for (long i = 0; i < 5; i++) { assertNotNull(this.mappedPageFactory.acquirePage(i)); TestUtil.sleepQuietly(1000); } indexSet = mappedPageFactory.getPageIndexSetBefore(start - 1000); assertTrue(indexSet.size() == 0); indexSet = mappedPageFactory.getPageIndexSetBefore(start + 2500); assertTrue(indexSet.size() == 3); indexSet = mappedPageFactory.getPageIndexSetBefore(start + 5000); assertTrue(indexSet.size() == 5); mappedPageFactory.deletePagesBefore(start + 2500); indexSet = mappedPageFactory.getExistingBackFileIndexSet(); assertTrue(indexSet.size() == 2); assertTrue(mappedPageFactory.getCacheSize() == 2); mappedPageFactory.releaseCachedPages(); assertTrue(mappedPageFactory.getCacheSize() == 0); assertTrue(((MappedPageFactoryImpl) mappedPageFactory).getLockMapSize() == 0); mappedPageFactory.deleteAllPages(); start = System.currentTimeMillis(); for (int i = 0; i <= 100; i++) { IMappedPage mappedPageI = mappedPageFactory.acquirePage(i); mappedPageI.getLocal(0).put(("hello " + i).getBytes()); mappedPageI.setDirty(true); ((MappedPageImpl) mappedPageI).flush(); long currentTime = System.currentTimeMillis(); long iPageFileLastModifiedTime = mappedPageFactory.getPageFileLastModifiedTime(i); assertTrue(iPageFileLastModifiedTime >= start); assertTrue(iPageFileLastModifiedTime <= currentTime); long index = mappedPageFactory.getFirstPageIndexBefore(currentTime + 1); assertTrue(index == i); start = currentTime; } mappedPageFactory.deleteAllPages(); // test wrapped case mappedPageFactory.acquirePage(Long.MAX_VALUE - 1); mappedPageFactory.acquirePage(Long.MAX_VALUE); long index = mappedPageFactory.getFirstPageIndexBefore(System.currentTimeMillis() + 1); assertTrue(index == Long.MAX_VALUE); mappedPageFactory.acquirePage(0); index = mappedPageFactory.getFirstPageIndexBefore(System.currentTimeMillis() + 1); assertTrue(index == 0); mappedPageFactory.acquirePage(1); index = mappedPageFactory.getFirstPageIndexBefore(System.currentTimeMillis() + 1); assertTrue(index == 1); }