Ejemplo n.º 1
0
  /**
   * Performs the compaction.
   *
   * @param scanner Where to read from.
   * @param writer Where to write to.
   * @param smallestReadPoint Smallest read point.
   * @param cleanSeqId When true, remove seqId(used to be mvcc) value which is <= smallestReadPoint
   * @return Whether compaction ended; false if it was interrupted for some reason.
   */
  protected boolean performCompaction(
      InternalScanner scanner, CellSink writer, long smallestReadPoint, boolean cleanSeqId)
      throws IOException {
    int bytesWritten = 0;
    // Since scanner.next() can return 'false' but still be delivering data,
    // we have to use a do/while loop.
    List<Cell> kvs = new ArrayList<Cell>();
    int closeCheckInterval = HStore.getCloseCheckInterval();
    long lastMillis;
    if (LOG.isDebugEnabled()) {
      lastMillis = System.currentTimeMillis();
    } else {
      lastMillis = 0;
    }
    boolean hasMore;
    do {
      hasMore = scanner.next(kvs, compactionKVMax);
      // output to writer:
      for (Cell c : kvs) {
        KeyValue kv = KeyValueUtil.ensureKeyValue(c);
        if (cleanSeqId && kv.getSequenceId() <= smallestReadPoint) {
          kv.setSequenceId(0);
        }
        writer.append(kv);
        ++progress.currentCompactedKVs;
        progress.totalCompactedSize += kv.getLength();

        // check periodically to see if a system stop is requested
        if (closeCheckInterval > 0) {
          bytesWritten += kv.getLength();
          if (bytesWritten > closeCheckInterval) {
            // Log the progress of long running compactions every minute if
            // logging at DEBUG level
            if (LOG.isDebugEnabled()) {
              long now = System.currentTimeMillis();
              if ((now - lastMillis) >= 60 * 1000) {
                LOG.debug(
                    "Compaction progress: "
                        + progress
                        + String.format(
                            ", rate=%.2f kB/sec",
                            (bytesWritten / 1024.0) / ((now - lastMillis) / 1000.0)));
                lastMillis = now;
              }
            }
            bytesWritten = 0;
            if (!store.areWritesEnabled()) {
              progress.cancel();
              return false;
            }
          }
        }
      }
      kvs.clear();
    } while (hasMore);
    progress.complete();
    return true;
  }