예제 #1
0
 /**
  * Remove the LedgerEntryPage from the clean page LRU map
  *
  * @param lep Ledger Entry Page object
  */
 private void removeFromCleanPageList(LedgerEntryPage lep) {
   synchronized (lruCleanPageMap) {
     if (!lep.isClean() || lep.inUse()) {
       lruCleanPageMap.remove(lep.getEntryKey());
     }
   }
 }
예제 #2
0
 /**
  * Add the LedgerEntryPage to the clean page LRU map
  *
  * @param lep Ledger Entry Page object
  */
 private void addToCleanPagesList(LedgerEntryPage lep) {
   synchronized (lruCleanPageMap) {
     if (lep.isClean() && !lep.inUse()) {
       lruCleanPageMap.put(lep.getEntryKey(), lep);
     }
   }
 }
예제 #3
0
 LedgerEntryPage getLedgerEntryPage(Long ledger, Long firstEntry, boolean onlyDirty) {
   LedgerEntryPage lep = pageMapAndList.getPage(ledger, firstEntry);
   if (onlyDirty && null != lep && lep.isClean()) {
     return null;
   }
   if (null != lep) {
     lep.usePage();
   }
   return lep;
 }
예제 #4
0
    /**
     * Get a clean page and provision it for the specified ledger and firstEntry within the ledger
     *
     * @param ledgerId Ledger id
     * @param firstEntry Id of the first entry in the page
     * @returns LedgerEntryPage if present
     */
    LedgerEntryPage grabCleanPage(long ledgerId, long firstEntry) {
      LedgerEntryPage lep = null;
      while (lruCleanPageMap.size() > 0) {
        lep = null;
        synchronized (lruCleanPageMap) {
          Iterator<Map.Entry<EntryKey, LedgerEntryPage>> iterator =
              lruCleanPageMap.entrySet().iterator();

          Map.Entry<EntryKey, LedgerEntryPage> entry = null;
          while (iterator.hasNext()) {
            entry = iterator.next();
            iterator.remove();
            if (entry.getValue().isClean() && !entry.getValue().inUse()) {
              lep = entry.getValue();
              break;
            }
          }

          if (null == lep) {
            LOG.debug("Did not find eligible page in the first pass");
            return null;
          }
        }

        // We found a candidate page, lets see if we can reclaim it before its re-used
        ConcurrentMap<Long, LedgerEntryPage> pageMap = pages.get(lep.getLedger());
        // Remove from map only if nothing has changed since we checked this lep.
        // Its possible for the ledger to have been deleted or the page to have already
        // been reclaimed. The page map is the definitive source of information, if anything
        // has changed we should leave this page along and continue iterating to find
        // another suitable page.
        if ((null != pageMap) && (pageMap.remove(lep.getFirstEntry(), lep))) {
          if (!lep.isClean()) {
            // Someone wrote to this page while we were reclaiming it.
            pageMap.put(lep.getFirstEntry(), lep);
            lep = null;
          } else {
            // Do some bookkeeping on the page table
            pages.remove(lep.getLedger(), EMPTY_PAGE_MAP);
            // We can now safely reset this lep and return it.
            lep.usePage();
            lep.zeroPage();
            lep.setLedgerAndFirstEntry(ledgerId, firstEntry);
            return lep;
          }
        } else {
          lep = null;
        }
      }
      return lep;
    }
예제 #5
0
 void updatePage(LedgerEntryPage lep) throws IOException {
   if (!lep.isClean()) {
     throw new IOException("Trying to update a dirty page");
   }
   FileInfo fi = null;
   try {
     fi = getFileInfo(lep.getLedger(), null);
     long pos = lep.getFirstEntryPosition();
     if (pos >= fi.size()) {
       lep.zeroPage();
     } else {
       lep.readPage(fi);
     }
   } finally {
     if (fi != null) {
       fi.release();
     }
   }
 }
예제 #6
0
    /**
     * Gets the list of pages in memory that have been changed and hence need to be written as a
     * part of the flush operation that is being issued
     *
     * @param ledgerId Ledger id
     * @returns last entry in the in memory pages.
     */
    private LinkedList<Long> getFirstEntryListToBeFlushed(long ledgerId) {
      ConcurrentMap<Long, LedgerEntryPage> pageMap = pages.get(ledgerId);
      if (pageMap == null || pageMap.isEmpty()) {
        return null;
      }

      LinkedList<Long> firstEntryList = new LinkedList<Long>();
      for (ConcurrentMap.Entry<Long, LedgerEntryPage> entry : pageMap.entrySet()) {
        LedgerEntryPage lep = entry.getValue();
        if (lep.isClean()) {
          if (!lep.inUse()) {
            addToCleanPagesList(lep);
          }
          if (LOG.isTraceEnabled()) {
            LOG.trace("Page is clean " + lep);
          }
        } else {
          firstEntryList.add(lep.getFirstEntry());
        }
      }
      return firstEntryList;
    }