public OCachePointer load(long fileId, long pageIndex) throws IOException { synchronized (syncObject) { final GroupKey groupKey = new GroupKey(fileId, pageIndex >>> 4); lockManager.acquireLock(Thread.currentThread(), groupKey, OLockManager.LOCK.SHARED); try { final WriteGroup writeGroup = writeGroups.get(groupKey); OCachePointer pagePointer; if (writeGroup == null) { pagePointer = cacheFileContent(fileId, pageIndex); pagePointer.incrementReferrer(); return pagePointer; } final int entryIndex = (int) (pageIndex & 15); pagePointer = writeGroup.pages[entryIndex]; if (pagePointer == null) pagePointer = cacheFileContent(fileId, pageIndex); pagePointer.incrementReferrer(); return pagePointer; } finally { lockManager.releaseLock(Thread.currentThread(), groupKey, OLockManager.LOCK.SHARED); } } }
@Override public Void call() throws Exception { final GroupKey firstKey = new GroupKey(fileId, 0); final GroupKey lastKey = new GroupKey(fileId, Long.MAX_VALUE); NavigableMap<GroupKey, WriteGroup> subMap = writeGroups.subMap(firstKey, true, lastKey, true); Iterator<Map.Entry<GroupKey, WriteGroup>> entryIterator = subMap.entrySet().iterator(); while (entryIterator.hasNext()) { Map.Entry<GroupKey, WriteGroup> entry = entryIterator.next(); WriteGroup writeGroup = entry.getValue(); GroupKey groupKey = entry.getKey(); lockManager.acquireLock(Thread.currentThread(), groupKey, OLockManager.LOCK.EXCLUSIVE); try { for (OCachePointer pagePointer : writeGroup.pages) { if (pagePointer != null) { pagePointer.acquireExclusiveLock(); try { pagePointer.decrementReferrer(); cacheSize.decrementAndGet(); } finally { pagePointer.releaseExclusiveLock(); } } } entryIterator.remove(); } finally { lockManager.releaseLock(Thread.currentThread(), groupKey, OLockManager.LOCK.EXCLUSIVE); } } return null; }
public Future store(final long fileId, final long pageIndex, final OCachePointer dataPointer) { Future future = null; synchronized (syncObject) { final GroupKey groupKey = new GroupKey(fileId, pageIndex >>> 4); lockManager.acquireLock(Thread.currentThread(), groupKey, OLockManager.LOCK.EXCLUSIVE); try { WriteGroup writeGroup = writeGroups.get(groupKey); if (writeGroup == null) { writeGroup = new WriteGroup(System.currentTimeMillis()); writeGroups.put(groupKey, writeGroup); } int entryIndex = (int) (pageIndex & 15); if (writeGroup.pages[entryIndex] == null) { dataPointer.incrementReferrer(); writeGroup.pages[entryIndex] = dataPointer; cacheSize.incrementAndGet(); } else { if (!writeGroup.pages[entryIndex].equals(dataPointer)) { writeGroup.pages[entryIndex].decrementReferrer(); dataPointer.incrementReferrer(); writeGroup.pages[entryIndex] = dataPointer; } } writeGroup.recencyBit = true; } finally { lockManager.releaseLock(Thread.currentThread(), groupKey, OLockManager.LOCK.EXCLUSIVE); } if (cacheSize.get() > cacheMaxSize) { future = commitExecutor.submit(new PeriodicFlushTask()); } return future; } }
public Set<ODirtyPage> logDirtyPagesTable() throws IOException { synchronized (syncObject) { if (writeAheadLog == null) return Collections.emptySet(); Set<ODirtyPage> logDirtyPages = new HashSet<ODirtyPage>(writeGroups.size() * 16); for (Map.Entry<GroupKey, WriteGroup> writeGroupEntry : writeGroups.entrySet()) { final GroupKey groupKey = writeGroupEntry.getKey(); final WriteGroup writeGroup = writeGroupEntry.getValue(); for (int i = 0; i < 16; i++) { final OCachePointer cachePointer = writeGroup.pages[i]; if (cachePointer != null) { final OLogSequenceNumber lastFlushedLSN = cachePointer.getLastFlushedLsn(); final String fileName = files.get(groupKey.fileId).getName(); final long pageIndex = (groupKey.groupIndex << 4) + i; final ODirtyPage logDirtyPage = new ODirtyPage(fileName, pageIndex, lastFlushedLSN); logDirtyPages.add(logDirtyPage); } } } writeAheadLog.logDirtyPages(logDirtyPages); return logDirtyPages; } }
@Override public Void call() throws Exception { final GroupKey firstKey = new GroupKey(fileId, 0); final GroupKey lastKey = new GroupKey(fileId, Long.MAX_VALUE); NavigableMap<GroupKey, WriteGroup> subMap = writeGroups.subMap(firstKey, true, lastKey, true); Iterator<Map.Entry<GroupKey, WriteGroup>> entryIterator = subMap.entrySet().iterator(); groupsLoop: while (entryIterator.hasNext()) { Map.Entry<GroupKey, WriteGroup> entry = entryIterator.next(); final WriteGroup writeGroup = entry.getValue(); final GroupKey groupKey = entry.getKey(); lockManager.acquireLock(Thread.currentThread(), groupKey, OLockManager.LOCK.EXCLUSIVE); try { int flushedPages = 0; for (int i = 0; i < 16; i++) { OCachePointer pagePointer = writeGroup.pages[i]; if (pagePointer != null) { if (!pagePointer.tryAcquireExclusiveLock()) continue groupsLoop; try { flushPage( groupKey.fileId, (groupKey.groupIndex << 4) + i, pagePointer.getDataPointer()); flushedPages++; } finally { pagePointer.releaseExclusiveLock(); } } } for (OCachePointer pagePointer : writeGroup.pages) if (pagePointer != null) pagePointer.decrementReferrer(); cacheSize.addAndGet(-flushedPages); entryIterator.remove(); } finally { lockManager.releaseLock( Thread.currentThread(), entry.getKey(), OLockManager.LOCK.EXCLUSIVE); } } files.get(fileId).synch(); return null; }
private int iterateBySubRing( NavigableMap<GroupKey, WriteGroup> subMap, int writeGroupsToFlush, int flushedWriteGroups, boolean forceFlush) throws IOException { Iterator<Map.Entry<GroupKey, WriteGroup>> entriesIterator = subMap.entrySet().iterator(); long currentTime = System.currentTimeMillis(); groupsLoop: while (entriesIterator.hasNext() && flushedWriteGroups < writeGroupsToFlush) { Map.Entry<GroupKey, WriteGroup> entry = entriesIterator.next(); final WriteGroup group = entry.getValue(); final GroupKey groupKey = entry.getKey(); final boolean weakLockMode = group.creationTime - currentTime < groupTTL && !forceFlush; if (group.recencyBit && weakLockMode) { group.recencyBit = false; continue; } lockManager.acquireLock( Thread.currentThread(), entry.getKey(), OLockManager.LOCK.EXCLUSIVE); try { if (group.recencyBit && weakLockMode) group.recencyBit = false; else { group.recencyBit = false; int flushedPages = 0; for (int i = 0; i < 16; i++) { final OCachePointer pagePointer = group.pages[i]; if (pagePointer != null) { if (!pagePointer.tryAcquireExclusiveLock()) continue groupsLoop; try { flushPage( groupKey.fileId, (groupKey.groupIndex << 4) + i, pagePointer.getDataPointer()); flushedPages++; final OLogSequenceNumber flushedLSN = ODurablePage.getLogSequenceNumberFromPage(pagePointer.getDataPointer()); pagePointer.setLastFlushedLsn(flushedLSN); } finally { pagePointer.releaseExclusiveLock(); } } } for (OCachePointer pagePointer : group.pages) if (pagePointer != null) pagePointer.decrementReferrer(); entriesIterator.remove(); flushedWriteGroups++; cacheSize.addAndGet(-flushedPages); } } finally { lockManager.releaseLock( Thread.currentThread(), entry.getKey(), OLockManager.LOCK.EXCLUSIVE); } lastGroupKey = groupKey; } return flushedWriteGroups; }