Пример #1
0
  private WriteBatchImpl readWriteBatch(SliceInput record, int updateSize) throws IOException {
    WriteBatchImpl writeBatch = new WriteBatchImpl();
    int entries = 0;
    while (record.isReadable()) {
      entries++;
      ValueType valueType = ValueType.getValueTypeByPersistentId(record.readByte());
      if (valueType == VALUE) {
        Slice key = readLengthPrefixedBytes(record);
        Slice value = readLengthPrefixedBytes(record);
        writeBatch.put(key, value);
      } else if (valueType == DELETION) {
        Slice key = readLengthPrefixedBytes(record);
        writeBatch.delete(key);
      } else {
        throw new IllegalStateException("Unexpected value type " + valueType);
      }
    }

    if (entries != updateSize) {
      throw new IOException(
          String.format(
              "Expected %d entries in log record but found %s entries", updateSize, entries));
    }

    return writeBatch;
  }
Пример #2
0
  private long recoverLogFile(long fileNumber, VersionEdit edit) throws IOException {
    Preconditions.checkState(mutex.isHeldByCurrentThread());
    File file = new File(databaseDir, Filename.logFileName(fileNumber));
    FileChannel channel = new FileInputStream(file).getChannel();
    try {
      LogMonitor logMonitor = LogMonitors.logMonitor();
      LogReader logReader = new LogReader(channel, logMonitor, true, 0);

      // Log(options_.info_log, "Recovering log #%llu", (unsigned long long) log_number);

      // Read all the records and add to a memtable
      long maxSequence = 0;
      MemTable memTable = null;
      for (Slice record = logReader.readRecord(); record != null; record = logReader.readRecord()) {
        SliceInput sliceInput = record.input();
        // read header
        if (sliceInput.available() < 12) {
          logMonitor.corruption(sliceInput.available(), "log record too small");
          continue;
        }
        long sequenceBegin = sliceInput.readLong();
        int updateSize = sliceInput.readInt();

        // read entries
        WriteBatchImpl writeBatch = readWriteBatch(sliceInput, updateSize);

        // apply entries to memTable
        if (memTable == null) {
          memTable = new MemTable(internalKeyComparator);
        }
        writeBatch.forEach(new InsertIntoHandler(memTable, sequenceBegin));

        // update the maxSequence
        long lastSequence = sequenceBegin + updateSize - 1;
        if (lastSequence > maxSequence) {
          maxSequence = lastSequence;
        }

        // flush mem table if necessary
        if (memTable.approximateMemoryUsage() > options.writeBufferSize()) {
          writeLevel0Table(memTable, edit, null);
          memTable = null;
        }
      }

      // flush mem table
      if (memTable != null && !memTable.isEmpty()) {
        writeLevel0Table(memTable, edit, null);
      }

      return maxSequence;
    } finally {
      channel.close();
    }
  }