public AbstractTransactionHandler(HStoreSite hstore_site, HStoreCoordinator hstore_coord) {
   this.hstore_site = hstore_site;
   this.hstore_conf = hstore_site.getHStoreConf();
   this.coordinator = hstore_coord;
   this.handler = this.coordinator.getHandler();
   this.num_sites = this.hstore_site.getCatalogContext().numberOfSites;
   this.local_site_id = hstore_site.getSiteId();
 }
  /**
   * Constructor
   *
   * @param executor
   */
  public AbstractTransaction(HStoreSite hstore_site) {
    this.hstore_site = hstore_site;
    int numPartitions = hstore_site.getCatalogContext().numberOfPartitions;

    this.released = new boolean[numPartitions];
    this.prepared = new boolean[numPartitions];
    this.finished = new boolean[numPartitions];
    this.round_state = new RoundState[numPartitions];
    this.round_ctr = new int[numPartitions];
    this.exec_readOnly = new boolean[numPartitions];
    this.exec_queueWork = new boolean[numPartitions];
    this.exec_eeWork = new boolean[numPartitions];

    this.exec_firstUndoToken = new long[numPartitions];
    this.exec_lastUndoToken = new long[numPartitions];
    this.exec_noUndoBuffer = new boolean[numPartitions];

    this.init_task = new InitializeTxnMessage(this);

    this.readTables = new boolean[numPartitions][];
    this.writeTables = new boolean[numPartitions][];

    Arrays.fill(this.exec_firstUndoToken, HStoreConstants.NULL_UNDO_LOGGING_TOKEN);
    Arrays.fill(this.exec_lastUndoToken, HStoreConstants.NULL_UNDO_LOGGING_TOKEN);
    Arrays.fill(this.exec_readOnly, true);
    Arrays.fill(this.exec_queueWork, false);
    Arrays.fill(this.exec_eeWork, false);
  }
  @Override
  public void run(ClientResponseImpl parameter) {
    if (debug.get())
      LOG.debug(
          String.format(
              "Got ClientResponse callback for txn #%d! Sending back to %s",
              parameter.getTransactionId(), HStoreThreadManager.formatSiteName(this.destSiteId)));
    FastSerializer fs = new FastSerializer();
    try {
      parameter.writeExternal(fs);
    } catch (IOException ex) {
      throw new RuntimeException(ex);
    }
    ByteString bs = ByteString.copyFrom(fs.getBuffer());
    TransactionRedirectResponse response =
        TransactionRedirectResponse.newBuilder()
            .setSenderSite(this.sourceSiteId)
            .setOutput(bs)
            .build();
    this.orig_callback.run(response);
    if (debug.get())
      LOG.debug(
          String.format(
              "Sent back ClientResponse for txn #%d to %s [bytes=%d]",
              parameter.getTransactionId(), HStoreThreadManager.formatSiteName(this.destSiteId)));

    // IMPORTANT: Since we're the only one that knows that we're finished (and actually even
    // cares), we need to be polite and clean-up after ourselves...
    try {
      this.finish();
      hstore_site.getObjectPools().CALLBACKS_TXN_REDIRECT_RESPONSE.returnObject(this);
    } catch (Exception ex) {
      throw new RuntimeException("Funky failure", ex);
    }
  }
 @Override
 public void run(TransactionRedirectResponse parameter) {
   if (LOG.isTraceEnabled())
     LOG.trace(
         String.format(
             "Got back FORWARD_TXN response from %s. Sending response to client [bytes=%d]",
             HStoreSite.formatSiteName(parameter.getSenderId()), parameter.getOutput().size()));
   byte data[] = parameter.getOutput().toByteArray();
   try {
     this.orig_callback.run(data);
   } catch (Throwable ex) {
     FastDeserializer fds = new FastDeserializer(data);
     ClientResponseImpl cresponse = null;
     long txn_id = -1;
     try {
       cresponse = fds.readObject(ClientResponseImpl.class);
       txn_id = cresponse.getTransactionId();
     } catch (IOException e) {
       LOG.fatal("We're really falling apart here!", e);
     }
     LOG.fatal("Failed to forward ClientResponse data back for txn #" + txn_id, ex);
     // throw ex;
   } finally {
     try {
       this.finish();
       HStoreObjectPools.CALLBACKS_TXN_REDIRECT_REQUEST.returnObject(this);
     } catch (Exception ex) {
       throw new RuntimeException("Funky failure", ex);
     }
   }
 }
 /**
  * Mark that this txn has executed a modifying query for the tableIds at the given partition.
  * <B>Note:</B> This is just tracking that we executed a query. It does not necessarily mean that
  * the query actually changed anything.
  *
  * @param partition
  * @param tableIds
  */
 public final void markTableIdsAsWritten(int partition, int... tableIds) {
   if (this.writeTables[partition] == null) {
     this.writeTables[partition] = new boolean[hstore_site.getCatalogContext().numberOfTables + 1];
   }
   for (int id : tableIds) {
     this.writeTables[partition][id] = true;
   } // FOR
 }
 public final WorkFragmentMessage getWorkFragmentMessage(WorkFragment fragment) {
   if (this.work_task == null) {
     this.work_task = new WorkFragmentMessage[hstore_site.getCatalogContext().numberOfPartitions];
   }
   int partition = fragment.getPartitionId();
   if (this.work_task[partition] == null) {
     this.work_task[partition] = new WorkFragmentMessage(this, fragment);
   } else {
     this.work_task[partition].setFragment(fragment);
   }
   return (this.work_task[partition]);
 }
  /**
   * Send a copy of a single message request to the partitions given as input If a partition is
   * managed by the local HStoreSite, then we will invoke the sendLocal() method. If it is on a
   * remote HStoreSite, then we will invoke sendRemote().
   *
   * @param ts
   * @param request
   * @param callback
   * @param partitions
   */
  public void sendMessages(
      LocalTransaction ts, T request, RpcCallback<U> callback, PartitionSet partitions) {
    // If this flag is true, then we'll invoke the local method
    // We want to do this *after* we send out all the messages to the remote sites
    // so that we don't have to wait as long for the responses to come back over the network
    boolean send_local = false;
    boolean site_sent[] = new boolean[this.num_sites];

    if (debug.val)
      LOG.debug(
          String.format(
              "Sending %s to %d partitions for %s",
              request.getClass().getSimpleName(), partitions.size(), ts));

    for (int partition : partitions.values()) {
      int dest_site_id = hstore_site.getCatalogContext().getSiteIdForPartitionId(partition);

      // Skip this HStoreSite if we're already sent it a message
      if (site_sent[dest_site_id]) continue;

      if (trace.val)
        LOG.trace(
            String.format(
                "Sending %s message to %s for %s",
                request.getClass().getSimpleName(),
                HStoreThreadManager.formatSiteName(dest_site_id),
                ts));

      // Local Partition
      if (this.local_site_id == dest_site_id) {
        send_local = true;
      }
      // Remote Partition
      else {
        HStoreService channel = coordinator.getChannel(dest_site_id);
        assert (channel != null) : "Invalid partition id '" + partition + "'";
        ProtoRpcController controller = this.getProtoRpcController(ts, dest_site_id);
        assert (controller != null)
            : "Invalid "
                + request.getClass().getSimpleName()
                + " ProtoRpcController for site #"
                + dest_site_id;
        this.sendRemote(channel, controller, request, callback);
      }
      site_sent[dest_site_id] = true;
    } // FOR
    // Optimization: We'll invoke sendLocal() after we have sent out
    // all of the messages to remote sites
    if (send_local) this.sendLocal(ts.getTransactionId(), request, partitions, callback);
  }
  @Override
  protected void setUp() throws Exception {
    super.setUp(ProjectType.TPCC);
    addPartitions(NUM_PARTITONS);

    Site catalog_site = CollectionUtil.first(CatalogUtil.getCluster(catalog).getSites());
    assertNotNull(catalog_site);
    hstore_site = HStore.initialize(catalog_site, HStoreConf.singleton());
    for (int p = 0; p < NUM_PARTITONS; p++) {
      PartitionExecutor site = new MockPartitionExecutor(p, catalog, p_estimator);
      hstore_site.addPartitionExecutor(p, site);
    } // FOR

    this.queue = new TransactionQueueManager(hstore_site);
  }
  @Override
  public synchronized void run() {
    final boolean d = debug.get();
    final boolean t = trace.get();

    if (this.first) {
      Thread self = Thread.currentThread();
      self.setName(
          HStoreThreadManager.getThreadName(hstore_site, HStoreConstants.THREAD_NAME_HELPER));
      hstore_site.getThreadManager().registerProcessingThread();
      this.first = false;
    }
    if (t) LOG.trace("New invocation of the ExecutionSiteHelper. Let's clean-up some txns!");

    this.hstore_site.updateLogging();
    for (PartitionExecutor es : this.executors) {
      //            if (t) LOG.trace(String.format("Partition %d has %d finished transactions",
      // es.partitionId, es.finished_txn_states.size()));
      //            long to_remove = System.currentTimeMillis() - this.txn_expire;

      int cleaned = 0;
      //            while (es.finished_txn_states.isEmpty() == false && (this.txn_per_round < 0 ||
      // cleaned < this.txn_per_round)) {
      //                AbstractTransaction ts = es.finished_txn_states.peek();
      //                if (ts.getEE_FinishedTimestamp() < to_remove) {
      ////                    if (traceLOG.info(String.format("Want to clean txn #%d [done=%s,
      // type=%s]", ts.getTransactionId(), ts.getHStoreSiteDone(), ts.getClass().getSimpleName()));
      //                    if (ts.isHStoreSite_Finished() == false) break;
      //
      //                    if (t) LOG.trace("Cleaning txn #" + ts.getTransactionId());
      //
      //
      //                    es.cleanupTransaction(ts);
      //                    es.finished_txn_states.remove();
      //                    cleaned++;
      //                    this.total_cleaned++;
      //                } else break;
      //            } // WHILE
      if (d && cleaned > 0)
        LOG.debug(
            String.format(
                "Cleaned %d TransactionStates at partition %d [total=%d]",
                cleaned, es.getPartitionId(), this.total_cleaned));
      // Only call tick here!
      //            es.tick();
    } // FOR

    // Recompute MarkovGraphs if we have them
    MarkovGraph m = null;
    while ((m = this.markovs_to_recompute.poll()) != null) {
      if (d)
        LOG.debug(
            String.format(
                "Recomputing MarkovGraph for %s [recomputed=%d, hashCode=%d]",
                m.getProcedure().getName(), m.getRecomputeCount(), m.hashCode()));
      m.calculateProbabilities();
      if (d && m.isValid() == false) {
        LOG.error("Invalid MarkovGraph after recomputing! Crashing...");
        Exception error =
            new Exception(
                String.format(
                    "Invalid %s MarkovGraph for after recomputing", m.getProcedure().getName()));
        this.hstore_site.getCoordinator().shutdownCluster(error);
      }
    } // WHILE
  }
 /**
  * Mark that this txn has executed a modifying query for the Table at the given partition.
  * <B>Note:</B> This is just tracking that we executed a query. It does not necessarily mean that
  * the query actually changed anything.
  *
  * @param partition
  * @param catalog_tbl
  */
 public final void markTableAsWritten(int partition, Table catalog_tbl) {
   if (this.writeTables[partition] == null) {
     this.writeTables[partition] = new boolean[hstore_site.getCatalogContext().numberOfTables + 1];
   }
   this.writeTables[partition][catalog_tbl.getRelativeIndex()] = true;
 }