protected QueueState checkQueueState() { QueueState newState = QueueState.UNBLOCKED; AbstractTransaction ts = super.peek(); if (ts == null) { if (t) LOG.trace(String.format("Partition %d :: Queue is empty.", this.partitionId)); newState = QueueState.BLOCKED_EMPTY; } // Check whether can unblock now else if (ts == this.nextTxn && this.state != QueueState.UNBLOCKED) { if (EstTime.currentTimeMillis() < this.blockTime) { newState = QueueState.BLOCKED_SAFETY; } else if (d) { LOG.debug( String.format( "Partition %d :: Wait time for %s has passed. Unblocking...", this.partitionId, this.nextTxn)); } } // This is a new txn and we should wait... else if (this.nextTxn != ts) { long txnTimestamp = TransactionIdManager.getTimestampFromTransactionId(ts.getTransactionId().longValue()); long timestamp = EstTime.currentTimeMillis(); long waitTime = Math.max(0, this.waitTime - (timestamp - txnTimestamp)); newState = (waitTime > 0 ? QueueState.BLOCKED_SAFETY : QueueState.UNBLOCKED); this.blockTime = timestamp + waitTime; this.nextTxn = ts; if (d) { String debug = ""; if (t) { Map<String, Object> m = new LinkedHashMap<String, Object>(); m.put("Txn Init Timestamp", txnTimestamp); m.put("Current Timestamp", timestamp); m.put("Block Time Remaining", (this.blockTime - timestamp)); debug = "\n" + StringUtil.formatMaps(m); } LOG.debug( String.format( "Partition %d :: Blocking %s for %d ms [maxWait=%d]%s", this.partitionId, ts, (this.blockTime - timestamp), this.waitTime, debug)); } } if (newState != this.state) { this.state = newState; if (d) LOG.debug( String.format( "Partition %d :: State:%s / NextTxn:%s", this.partitionId, this.state, this.nextTxn)); } return this.state; }
/** Only return transaction state objects that are ready to run. */ @Override public AbstractTransaction poll() { AbstractTransaction retval = null; // These invocations of poll() can return null if the next // txn was speculatively executed if (this.nextTxn == null) this.checkQueueState(); if (this.state == QueueState.BLOCKED_SAFETY) { if (EstTime.currentTimeMillis() >= this.blockTime) { retval = super.poll(); } } else if (this.state == QueueState.UNBLOCKED) { // assert(checkQueueState() == QueueState.UNBLOCKED); retval = super.poll(); } if (retval != null) { assert (this.nextTxn.equals(retval)) : String.format( "Partition %d :: Next txn is %s but our poll returned %s\n" + StringUtil.SINGLE_LINE + "%s", this.partitionId, this.nextTxn, retval, this.debug()); this.nextTxn = null; this.lastTxnPopped = retval.getTransactionId(); } if (d && retval != null) LOG.debug(String.format("Partition %d :: poll() -> %s", this.partitionId, retval)); this.checkQueueState(); return retval; }
public String debug() { Map<String, Object> m = new LinkedHashMap<String, Object>(); m.put("PartitionId", this.partitionId); m.put("# of Elements", this.size()); m.put("Wait Time", this.waitTime); m.put("Next Time Remaining", Math.max(0, EstTime.currentTimeMillis() - this.blockTime)); m.put("Next Txn", this.nextTxn); m.put("Last Popped Txn", this.lastTxnPopped); m.put("Last Seen Txn", this.lastSeenTxn); return (StringUtil.formatMaps(m)); }
@Override public void remoteHandler( RpcController controller, TransactionMapRequest request, RpcCallback<TransactionMapResponse> callback) { assert (request.hasTransactionId()) : "Got " + request.getClass().getSimpleName() + " without a txn id!"; Long txn_id = Long.valueOf(request.getTransactionId()); if (debug.val) LOG.debug(String.format("Got %s for txn #%d", request.getClass().getSimpleName(), txn_id)); // The mr_ts handle will be null if this HStoreSite is not where the // base partition for the original MRTransaction MapReduceTransaction mr_ts = hstore_site.getTransaction(txn_id); if (mr_ts == null) { mr_ts = hstore_site .getTransactionInitializer() .createMapReduceTransaction( txn_id, EstTime.currentTimeMillis(), request.getClientHandle(), request.getBasePartition(), request.getProcedureId(), request.getParams().asReadOnlyByteBuffer()); } assert (mr_ts.isMapPhase()); mr_ts.initTransactionMapWrapperCallback(callback); /* * Here we would like to start MapReduce Transaction on the remote partition except the base partition of it. * This is to avoid the double invoke for remote task. * */ for (int partition : hstore_site.getLocalPartitionIds()) { if (partition != mr_ts.getBasePartition()) { LocalTransaction ts = mr_ts.getLocalTransaction(partition); hstore_site.transactionStart(ts); } } // FOR }
protected FixedEstimatorState(CatalogContext catalogContext, Long txn_id, int base_partition) { super(catalogContext); this.init(txn_id, base_partition, EstTime.currentTimeMillis()); }