Example #1
0
  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;
    }
  }
Example #2
0
    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;
    }