Esempio n. 1
0
  public void close() {
    if (shuttingDown.getAndSet(true)) {
      return;
    }

    mutex.lock();
    try {
      while (backgroundCompaction != null) {
        backgroundCondition.awaitUninterruptibly();
      }
    } finally {
      mutex.unlock();
    }

    compactionExecutor.shutdown();
    try {
      compactionExecutor.awaitTermination(1, TimeUnit.DAYS);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
    try {
      versions.destroy();
    } catch (IOException ignored) {
    }
    try {
      log.close();
    } catch (IOException ignored) {
    }
    tableCache.close();
    dbLock.release();
  }
Esempio n. 2
0
  private void finishCompactionOutputFile(CompactionState compactionState) throws IOException {
    Preconditions.checkNotNull(compactionState, "compactionState is null");
    Preconditions.checkArgument(compactionState.outfile != null);
    Preconditions.checkArgument(compactionState.builder != null);

    long outputNumber = compactionState.currentFileNumber;
    Preconditions.checkArgument(outputNumber != 0);

    long currentEntries = compactionState.builder.getEntryCount();
    compactionState.builder.finish();

    long currentBytes = compactionState.builder.getFileSize();
    compactionState.currentFileSize = currentBytes;
    compactionState.totalBytes += currentBytes;

    FileMetaData currentFileMetaData =
        new FileMetaData(
            compactionState.currentFileNumber,
            compactionState.currentFileSize,
            compactionState.currentSmallest,
            compactionState.currentLargest);
    compactionState.outputs.add(currentFileMetaData);

    compactionState.builder = null;

    compactionState.outfile.force(true);
    compactionState.outfile.close();
    compactionState.outfile = null;

    if (currentEntries > 0) {
      // Verify that the table is usable
      tableCache.newIterator(outputNumber);
    }
  }
Esempio n. 3
0
  private void deleteObsoleteFiles() {
    Preconditions.checkState(mutex.isHeldByCurrentThread());

    // Make a set of all of the live files
    List<Long> live = newArrayList(this.pendingOutputs);
    for (FileMetaData fileMetaData : versions.getLiveFiles()) {
      live.add(fileMetaData.getNumber());
    }

    for (File file : Filename.listFiles(databaseDir)) {
      FileInfo fileInfo = Filename.parseFileName(file);
      if (fileInfo == null) continue;
      long number = fileInfo.getFileNumber();
      boolean keep = true;
      switch (fileInfo.getFileType()) {
        case LOG:
          keep = ((number >= versions.getLogNumber()) || (number == versions.getPrevLogNumber()));
          break;
        case DESCRIPTOR:
          // Keep my manifest file, and any newer incarnations'
          // (in case there is a race that allows other incarnations)
          keep = (number >= versions.getManifestFileNumber());
          break;
        case TABLE:
          keep = live.contains(number);
          break;
        case TEMP:
          // Any temp files that are currently being written to must
          // be recorded in pending_outputs_, which is inserted into "live"
          keep = live.contains(number);
          break;
        case CURRENT:
        case DB_LOCK:
        case INFO_LOG:
          keep = true;
          break;
      }

      if (!keep) {
        if (fileInfo.getFileType() == FileType.TABLE) {
          tableCache.evict(number);
        }
        // todo info logging system needed
        //                Log(options_.info_log, "Delete type=%d #%lld\n",
        //                int(type),
        //                        static_cast < unsigned long long>(number));
        file.delete();
      }
    }
  }
Esempio n. 4
0
  private FileMetaData buildTable(SeekingIterable<InternalKey, Slice> data, long fileNumber)
      throws IOException {
    File file = new File(databaseDir, Filename.tableFileName(fileNumber));
    try {
      InternalKey smallest = null;
      InternalKey largest = null;
      FileChannel channel = new FileOutputStream(file).getChannel();
      try {
        TableBuilder tableBuilder =
            new TableBuilder(options, channel, new InternalUserComparator(internalKeyComparator));

        for (Entry<InternalKey, Slice> entry : data) {
          // update keys
          InternalKey key = entry.getKey();
          if (smallest == null) {
            smallest = key;
          }
          largest = key;

          tableBuilder.add(key.encode(), entry.getValue());
        }

        tableBuilder.finish();
      } finally {
        try {
          channel.force(true);
        } finally {
          channel.close();
        }
      }

      if (smallest == null) {
        return null;
      }
      FileMetaData fileMetaData = new FileMetaData(fileNumber, file.length(), smallest, largest);

      // verify table can be opened
      tableCache.newIterator(fileMetaData);

      pendingOutputs.remove(fileNumber);

      return fileMetaData;

    } catch (IOException e) {
      file.delete();
      throw e;
    }
  }