/** * */ package edu.brown.api; import java.util.Collection; import java.util.concurrent.atomic.AtomicInteger; import org.apache.log4j.Logger; import org.voltdb.CatalogContext; import org.voltdb.catalog.Table; import org.voltdb.client.Client; import org.voltdb.client.ClientResponse; import org.voltdb.client.ProcedureCallback; import org.voltdb.sysprocs.EvictTuples; /** * Special thread to execute the @EvictTuples sysproc and update * the BenchmarkInterests accordingly. * @author pavlo */ public class PeriodicEvictionThread implements Runnable, ProcedureCallback { private static final Logger LOG = Logger.getLogger(PeriodicEvictionThread.class); private final CatalogContext catalogContext; private final Client client; private final String procName = "@" + EvictTuples.class.getSimpleName(); private final String tableNames[]; private final long evictionSize[]; private final Collection<BenchmarkInterest> printers; private final AtomicInteger callbacks = new AtomicInteger(); public PeriodicEvictionThread(CatalogContext catalogContext, Client client, long blockSize, Collection<BenchmarkInterest> printers) { this.catalogContext = catalogContext; this.client = client; this.printers = printers; Collection<Table> evictables = this.catalogContext.getEvictableTables(); this.tableNames = new String[evictables.size()]; this.evictionSize = new long[this.tableNames.length]; int i = 0; for (Table catalog_tbl : evictables) { this.tableNames[i] = catalog_tbl.getName(); this.evictionSize[i] = blockSize; i++; } // FOR } @Override public void run() { if (this.callbacks.get() != 0) return; this.callbacks.set(catalogContext.numberOfPartitions); LOG.info("Invoking " + this.procName + " on " + catalogContext.numberOfPartitions + " partitions"); // Let all our BenchmarkInterests know that we are doing an eviction now for (BenchmarkInterest b : this.printers) { b.markEvictionStart(); } // FOR for (int p = 0; p < catalogContext.numberOfPartitions; p++) { try { this.client.callProcedure(this, this.procName, p, this.tableNames, null, this.evictionSize); } catch (Exception ex) { String msg = "Failed to invoke " + this.procName + " for partition #" + p; throw new RuntimeException(msg, ex); } } // FOR } @Override public void clientCallback(ClientResponse clientResponse) { if (LOG.isDebugEnabled()) LOG.debug(clientResponse); if (this.callbacks.decrementAndGet() == 0) { for (BenchmarkInterest b : this.printers) { b.markEvictionStop(); } // FOR } } }