Example #1
0
 /**
  * Returns the key bounds for the provided log file.
  *
  * @return the pair of (lowest key, highest key) that correspond to records stored in the
  *     corresponding log file.
  * @throws ChangelogException if an error occurs while retrieving the keys
  */
 private Pair<K, K> getKeyBounds(final LogFile<K, V> logFile) throws ChangelogException {
   try {
     final String name = logFile.getFile().getName();
     final String[] keys =
         name.substring(0, name.length() - Log.LOG_FILE_SUFFIX.length())
             .split(LOG_FILE_NAME_SEPARATOR);
     return Pair.of(
         recordParser.decodeKeyFromString(keys[0]), recordParser.decodeKeyFromString(keys[1]));
   } catch (Exception e) {
     throw new ChangelogException(
         ERR_CHANGELOG_UNABLE_TO_RETRIEVE_KEY_BOUNDS_FROM_FILE.get(logFile.getFile().getPath()),
         e);
   }
 }
Example #2
0
 /**
  * Purge the log up to and excluding the provided key.
  *
  * @param purgeKey the key up to which purging must happen
  * @return the oldest non purged record, or {@code null} if no record was purged
  * @throws ChangelogException if a database problem occurs.
  */
 public Record<K, V> purgeUpTo(final K purgeKey) throws ChangelogException {
   exclusiveLock.lock();
   try {
     if (isClosed) {
       return null;
     }
     final SortedMap<K, LogFile<K, V>> logFilesToPurge = logFiles.headMap(purgeKey);
     if (logFilesToPurge.isEmpty()) {
       return null;
     }
     final List<String> undeletableFiles = new ArrayList<>();
     final Iterator<LogFile<K, V>> entriesToPurge = logFilesToPurge.values().iterator();
     while (entriesToPurge.hasNext()) {
       final LogFile<K, V> logFile = entriesToPurge.next();
       try {
         abortCursorsOpenOnLogFile(logFile);
         logFile.close();
         logFile.delete();
         entriesToPurge.remove();
       } catch (ChangelogException e) {
         // The deletion of log file on file system has failed
         undeletableFiles.add(logFile.getFile().getPath());
       }
     }
     if (!undeletableFiles.isEmpty()) {
       throw new ChangelogException(
           ERR_CHANGELOG_UNABLE_TO_DELETE_LOG_FILE_WHILE_PURGING.get(
               Utils.joinAsString(", ", undeletableFiles)));
     }
     return getOldestRecord();
   } finally {
     exclusiveLock.unlock();
   }
 }
Example #3
0
  /**
   * Empties the log, discarding all records it contains.
   *
   * <p>All cursors open on the log are aborted.
   *
   * @throws ChangelogException If cursors are opened on this log, or if a problem occurs during
   *     clearing operation.
   */
  public void clear() throws ChangelogException {
    exclusiveLock.lock();
    try {
      if (isClosed) {
        return;
      }
      if (!openCursors.isEmpty()) {
        // All open cursors are aborted, which means the change number indexer thread
        // should manage AbortedChangelogCursorException specifically to avoid being
        // stopped
        abortAllOpenCursors();
      }

      // delete all log files
      final List<String> undeletableFiles = new ArrayList<>();
      for (LogFile<K, V> logFile : logFiles.values()) {
        try {
          logFile.close();
          logFile.delete();
        } catch (ChangelogException e) {
          undeletableFiles.add(logFile.getFile().getPath());
        }
      }
      if (!undeletableFiles.isEmpty()) {
        throw new ChangelogException(
            ERR_CHANGELOG_UNABLE_TO_DELETE_LOG_FILE.get(
                Utils.joinAsString(", ", undeletableFiles)));
      }
      logFiles.clear();

      // recreate an empty head log file
      openHeadLogFile();
    } catch (Exception e) {
      throw new ChangelogException(
          ERR_ERROR_CLEARING_DB.get(logPath.getPath(), stackTraceToSingleLineString(e)));
    } finally {
      exclusiveLock.unlock();
    }
  }
Example #4
0
 private boolean isHeadLogFile(final LogFile<K, V> logFile) {
   return logFile.getFile().getName().equals(Log.HEAD_LOG_FILE_NAME);
 }
Example #5
0
 /**
  * Dump this log as a text files, intended for debugging purpose only.
  *
  * @param dumpDirectory Directory that will contains log files with text format and ".txt"
  *     extensions
  * @throws ChangelogException If an error occurs during dump
  */
 void dumpAsTextFile(File dumpDirectory) throws ChangelogException {
   for (LogFile<K, V> logFile : logFiles.values()) {
     logFile.dumpAsTextFile(new File(dumpDirectory, logFile.getFile().getName() + ".txt"));
   }
 }
Example #6
0
 @Override
 public String toString() {
   return String.format(
       "Cursor on log : %s, current log file: %s, current cursor: %s",
       log.logPath, currentLogFile.getFile().getName(), currentCursor);
 }