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.checkPage((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)
{
log.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);
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)
{
}
cache.unlock();
}
}
return cache;
}