Package co.cask.cdap.data2.transaction.queue.leveldb

Source Code of co.cask.cdap.data2.transaction.queue.leveldb.LevelDBQueueEvictor

/*
* Copyright © 2014 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package co.cask.cdap.data2.transaction.queue.leveldb;

import co.cask.cdap.api.dataset.table.Row;
import co.cask.cdap.api.dataset.table.Scanner;
import co.cask.cdap.common.queue.QueueName;
import co.cask.cdap.data2.dataset2.lib.table.leveldb.LevelDBOrderedTableCore;
import co.cask.cdap.data2.transaction.queue.QueueEntryRow;
import co.cask.cdap.data2.transaction.queue.QueueEvictor;
import co.cask.tephra.Transaction;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

/**
* An evictor for the levelDB based queues.
*/
public class LevelDBQueueEvictor implements QueueEvictor {

  private static final Logger LOG = LoggerFactory.getLogger(LevelDBQueueEvictor.class);

  private final LevelDBOrderedTableCore core;
  private final byte[] queueRowPrefix;
  private final Executor executor;
  private final int numGroups;
  private final QueueName name;

  public LevelDBQueueEvictor(LevelDBOrderedTableCore core, QueueName queueName, int numGroups, Executor executor) {
    this.core = core;
    this.executor = executor;
    this.queueRowPrefix = QueueEntryRow.getQueueRowPrefix(queueName);
    this.numGroups = numGroups;
    this.name = queueName;
  }

  @Override
  public ListenableFuture<Integer> evict(final Transaction transaction) {
    final SettableFuture<Integer> result = SettableFuture.create();
    executor.execute(new Runnable() {

      @Override
      public void run() {
        try {
          result.set(doEvict(transaction));
        } catch (Throwable t) {
          result.setException(t);
        }
      }
    });
    return result;
  }

  private synchronized int doEvict(Transaction transaction) throws IOException {
    final byte[] stopRow = QueueEntryRow.getStopRowForTransaction(queueRowPrefix, transaction);
    Row row;
    List<byte[]> rowsToDelete = Lists.newArrayList();
    // the scan must be non-transactional in order to see the state columns (which have latest timestamp)
    Scanner scanner = core.scan(queueRowPrefix, stopRow, null, null, Transaction.ALL_VISIBLE_LATEST);
    try {
      while ((row = scanner.next()) != null) {
        int processed = 0;
        for (Map.Entry<byte[], byte[]> entry : row.getColumns().entrySet()) {
          // is it a state column for a consumer instance?
          if (!QueueEntryRow.isStateColumn(entry.getKey())) {
            continue;
          }
          // is the write pointer of this state committed w.r.t. the current transaction, and is it processed?
          if (QueueEntryRow.isCommittedProcessed(entry.getValue(), transaction)) {
            ++processed;
          }
        }
        if (processed >= numGroups) {
          rowsToDelete.add(row.getRow());
        }
      }
    } finally {
      scanner.close();
    }
    if (!rowsToDelete.isEmpty()) {
      core.deleteRows(rowsToDelete);
      LOG.trace("Evicted {} entries from queue {}", rowsToDelete.size(), name);
    } else {
      LOG.trace("Nothing to evict from queue {}", name);
    }
    return rowsToDelete.size();
  }
}
TOP

Related Classes of co.cask.cdap.data2.transaction.queue.leveldb.LevelDBQueueEvictor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.