Beispiel #1
0
 /** Abort all cursors opened on the provided log file. */
 private void abortCursorsOpenOnLogFile(LogFile<K, V> logFile) {
   for (AbortableLogCursor<K, V> cursor : openCursors) {
     if (cursor.isAccessingLogFile(logFile)) {
       cursor.abort();
     }
   }
 }
Beispiel #2
0
 /**
  * Returns a cursor that allows to retrieve the records from this log. The starting position is
  * defined by the provided key, cursor matching strategy and cursor positioning strategy.
  *
  * @param key Key to use as a start position for the cursor. If key is {@code null}, cursor will
  *     point at the first record of the log.
  * @param matchingStrategy Cursor key matching strategy.
  * @param positionStrategy The cursor positioning strategy.
  * @return a cursor on the log records, which is never {@code null}
  * @throws ChangelogException If the cursor can't be created.
  */
 public RepositionableCursor<K, V> getCursor(
     final K key,
     final KeyMatchingStrategy matchingStrategy,
     final PositionStrategy positionStrategy)
     throws ChangelogException {
   if (key == null) {
     return getCursor();
   }
   AbortableLogCursor<K, V> cursor = null;
   sharedLock.lock();
   try {
     if (isClosed) {
       return new EmptyCursor<>();
     }
     cursor = new AbortableLogCursor<>(this, new InternalLogCursor<K, V>(this));
     final boolean isSuccessfullyPositioned =
         cursor.positionTo(key, matchingStrategy, positionStrategy);
     // Allow for cursor re-initialization after exhaustion in case of
     // LESS_THAN_OR_EQUAL_TO_KEY ands GREATER_THAN_OR_EQUAL_TO_KEY strategies
     if (isSuccessfullyPositioned || matchingStrategy != EQUAL_TO_KEY) {
       registerCursor(cursor);
       return cursor;
     } else {
       StaticUtils.close(cursor);
       return new EmptyCursor<>();
     }
   } catch (ChangelogException e) {
     StaticUtils.close(cursor);
     throw e;
   } finally {
     sharedLock.unlock();
   }
 }
Beispiel #3
0
 /**
  * Disable the cursors opened on the head log file log, by closing their underlying cursor.
  * Returns the state of each cursor just before the close operation.
  *
  * @return the pairs (cursor, cursor state) for each cursor pointing to head log file.
  * @throws ChangelogException If an error occurs.
  */
 private List<Pair<AbortableLogCursor<K, V>, CursorState<K, V>>> disableOpenedCursorsOnHead()
     throws ChangelogException {
   final List<Pair<AbortableLogCursor<K, V>, CursorState<K, V>>> openCursorsStates =
       new ArrayList<>();
   final LogFile<K, V> headLogFile = getHeadLogFile();
   for (AbortableLogCursor<K, V> cursor : openCursors) {
     if (cursor.isAccessingLogFile(headLogFile)) {
       openCursorsStates.add(Pair.of(cursor, cursor.getState()));
       cursor.closeUnderlyingCursor();
     }
   }
   return openCursorsStates;
 }
Beispiel #4
0
  /** Update the cursors that were pointing to head after a rotation of the head log file. */
  private void updateOpenedCursorsOnHeadAfterRotation(
      List<Pair<AbortableLogCursor<K, V>, CursorState<K, V>>> cursors) throws ChangelogException {
    for (Pair<AbortableLogCursor<K, V>, CursorState<K, V>> pair : cursors) {
      final CursorState<K, V> cursorState = pair.getSecond();

      // Need to update the cursor only if it is pointing to the head log file
      if (cursorState.isValid() && isHeadLogFile(cursorState.logFile)) {
        final K previousKey = logFiles.lowerKey(recordParser.getMaxKey());
        final LogFile<K, V> logFile = findLogFileFor(previousKey);
        final AbortableLogCursor<K, V> cursor = pair.getFirst();
        cursor.reinitializeTo(
            new CursorState<K, V>(logFile, cursorState.filePosition, cursorState.record));
      }
    }
  }
Beispiel #5
0
 /**
  * Returns a cursor that allows to retrieve the records from this log, starting at the first
  * position.
  *
  * @return a cursor on the log records, which is never {@code null}
  * @throws ChangelogException If the cursor can't be created.
  */
 public RepositionableCursor<K, V> getCursor() throws ChangelogException {
   AbortableLogCursor<K, V> cursor = null;
   sharedLock.lock();
   try {
     if (isClosed) {
       return new EmptyCursor<>();
     }
     cursor = new AbortableLogCursor<>(this, new InternalLogCursor<K, V>(this));
     cursor.positionTo(null, null, null);
     registerCursor(cursor);
     return cursor;
   } catch (ChangelogException e) {
     StaticUtils.close(cursor);
     throw e;
   } finally {
     sharedLock.unlock();
   }
 }
Beispiel #6
0
 private void abortAllOpenCursors() throws ChangelogException {
   for (AbortableLogCursor<K, V> cursor : openCursors) {
     cursor.abort();
   }
 }