コード例 #1
0
  /**
   * Skip a specified number of entries and return the resulting position.
   *
   * @param startPosition the current position
   * @param entriesToSkip the numbers of entries to skip
   * @return the new position
   */
  protected synchronized Position skipEntries(Position startPosition, int entriesToSkip) {
    log.debug("[{}] Skipping {} entries from position {}", va(name, entriesToSkip, startPosition));
    long ledgerId = startPosition.getLedgerId();
    entriesToSkip += startPosition.getEntryId();

    while (entriesToSkip > 0) {
      if (currentLedger != null && ledgerId == currentLedger.getId()) {
        checkArgument(entriesToSkip <= (currentLedger.getLastAddConfirmed() + 1));
        return new Position(ledgerId, entriesToSkip);
      } else {
        LedgerStat ledger = ledgers.get(ledgerId);
        if (ledger == null) {
          checkArgument(!ledgers.isEmpty());
          ledgerId = ledgers.ceilingKey(ledgerId);
          continue;
        }

        if (entriesToSkip < ledger.getEntriesCount()) {
          return new Position(ledgerId, entriesToSkip);
        } else {
          // Move to next ledger
          entriesToSkip -= ledger.getEntriesCount();
          ledgerId = ledgers.ceilingKey(ledgerId + 1);
        }
      }
    }

    return new Position(ledgerId, 0);
  }
コード例 #2
0
  protected synchronized boolean hasMoreEntries(Position position) {
    if (position.getLedgerId() == currentLedger.getId()) {
      // If we are reading from the last ledger, use the
      // LedgerHandle metadata
      return position.getEntryId() <= currentLedger.getLastAddConfirmed();
    } else if (currentLedger.getLastAddConfirmed() >= 0) {
      // We have entries in the current ledger and we are reading from an
      // older ledger
      return true;
    } else {
      // At this point, currentLedger is empty, we need to check in the
      // older ledgers for entries past the current position
      LedgerStat ls = ledgers.get(position.getLedgerId());
      if (ls == null) {
        // The cursor haven't been initialized yet
        checkArgument(position.getLedgerId() == -1);
        return true;
      } else if (position.getEntryId() < ls.getEntriesCount()) {
        // There are still entries to read in the current reading ledger
        return true;
      } else {
        for (LedgerStat stat : ledgers.tailMap(position.getLedgerId(), false).values()) {
          if (stat.getEntriesCount() > 0) return true;
        }

        return false;
      }
    }
  }
コード例 #3
0
  /**
   * Validate whether a specified position is valid for the current managed ledger.
   *
   * @param position the position to validate
   * @return true if the position is valid, false otherwise
   */
  protected synchronized boolean isValidPosition(Position position) {
    if (position.getLedgerId() == currentLedger.getId()) {
      return position.getEntryId() <= currentLedger.getLastAddConfirmed();
    } else {
      // Look in the ledgers map
      LedgerStat ls = ledgers.get(position.getLedgerId());
      if (ls == null) return false;

      return position.getEntryId() < ls.getEntriesCount();
    }
  }
コード例 #4
0
  protected synchronized long getNumberOfEntries(Position position) {
    long count = 0;
    // First count the number of unread entries in the ledger pointed by
    // position
    if (position.getLedgerId() >= 0)
      count += ledgers.get(position.getLedgerId()).getEntriesCount() - position.getEntryId();

    // Then, recur all the next ledgers and sum all the entries they contain
    for (LedgerStat ls : ledgers.tailMap(position.getLedgerId(), false).values()) {
      count += ls.getEntriesCount();
    }

    // Last add the entries in the current ledger
    if (state != State.ClosedLedger) {
      count += currentLedger.getLastAddConfirmed() + 1;
    }

    return count;
  }
コード例 #5
0
  /**
   * Delete this ManagedLedger completely from the system.
   *
   * @throws Exception
   */
  protected void delete() throws InterruptedException, ManagedLedgerException {
    close();

    synchronized (this) {
      checkFenced();

      try {
        for (LedgerStat ls : ledgers.values()) {
          log.debug("[{}] Deleting ledger {}", name, ls);
          try {
            bookKeeper.deleteLedger(ls.getLedgerId());
          } catch (BKNoSuchLedgerExistsException e) {
            log.warn("[{}] Ledger {} not found when deleting it", name, ls.getLedgerId());
          }
        }
      } catch (BKException e) {
        throw new ManagedLedgerException(e);
      }

      store.removeManagedLedger(name);
    }
  }
コード例 #6
0
  /**
   * Checks whether there are ledger that have been fully consumed and deletes them
   *
   * @throws Exception
   */
  protected void internalTrimConsumedLedgers() {
    // Ensure only one trimming operation is active
    List<LedgerStat> ledgersToDelete = Lists.newArrayList();

    synchronized (this) {
      long slowestReaderLedgerId = -1;
      if (cursors.isEmpty() && currentLedger != null) {
        // At this point the lastLedger will be pointing to the
        // ledger that has just been closed, therefore the +1 to
        // include lastLedger in the trimming.
        slowestReaderLedgerId = currentLedger.getId() + 1;
      } else {
        slowestReaderLedgerId = cursors.getSlowestReaderPosition().getLedgerId();
      }

      for (LedgerStat ls : ledgers.headMap(slowestReaderLedgerId, false).values()) {
        ledgersToDelete.add(ls);
        ledgerCache.invalidate(ls.getLedgerId());
      }

      if (ledgersToDelete.isEmpty()) {
        return;
      }
    }

    // Delete the ledgers _without_ holding the lock on 'this'
    long removedCount = 0;
    long removedSize = 0;

    for (LedgerStat ls : ledgersToDelete) {
      log.info("[{}] Removing ledger {}", name, ls.getLedgerId());
      try {
        bookKeeper.deleteLedger(ls.getLedgerId());
        ++removedCount;
        removedSize += ls.getSize();
      } catch (BKNoSuchLedgerExistsException e) {
        log.warn("[{}] Ledger was already deleted {}", name, ls.getLedgerId());
      } catch (Exception e) {
        log.error("[{}] Error deleting ledger {}", name, ls.getLedgerId());
        return;
      }
    }

    // Update metadata
    try {
      synchronized (this) {
        numberOfEntries.addAndGet(-removedCount);
        totalSize.addAndGet(-removedSize);
        for (LedgerStat ls : ledgersToDelete) {
          ledgers.remove(ls.getLedgerId());
        }

        if (state == State.CreatingLedger) {
          // The list of ledgers is being modified asynchronously, we
          // cannot update it now. In case of a client crash, this
          // will just result in some ledgers to be deleted twice,
          // without any side consequences.
          log.info("[{}] Skipped updating ledger list for concurrent modification", name);
          return;
        }

        ledgersVersion = store.updateLedgersIds(name, ledgers.values(), ledgersVersion);
      }
    } catch (MetaStoreException e) {
      log.error("[{}] Failed to update the list of ledgers after trimming", name, e);
    }
  }