public PageCache getPageCache(final long pageId) { try { boolean needToRead = false; PageCache cache = null; synchronized (softCache) { if (pageId > pagingStore.getCurrentWritingPage()) { return null; } cache = softCache.get(pageId); if (cache == null) { if (!pagingStore.checkPageFileExists((int) pageId)) { return null; } cache = createPageCache(pageId); needToRead = true; // anyone reading from this cache will have to wait reading to finish first // we also want only one thread reading this cache cache.lock(); if (isTrace) { HornetQServerLogger.LOGGER.trace( "adding " + pageId + " into cursor = " + this.pagingStore.getAddress()); } softCache.put(pageId, cache); } } // Reading is done outside of the synchronized block, however // the page stays locked until the entire reading is finished if (needToRead) { Page page = null; try { page = pagingStore.createPage((int) pageId); storageManager.beforePageRead(); page.open(); List<PagedMessage> pgdMessages = page.read(storageManager); cache.setMessages(pgdMessages.toArray(new PagedMessage[pgdMessages.size()])); } finally { try { if (page != null) { page.close(); } } catch (Throwable ignored) { } storageManager.afterPageRead(); cache.unlock(); } } return cache; } catch (Exception e) { throw new RuntimeException( "Couldn't complete paging due to an IO Exception on Paging - " + e.getMessage(), e); } }
/* Protected as we may let test cases to instrument the test */ protected PageCacheImpl createPageCache(final long pageId) throws Exception { return new PageCacheImpl(pagingStore.createPage((int) pageId)); }