result = mr_ts.getMapOutputByPartition(this.partitionId);
// Always invoke the TransactionMapWrapperCallback to let somebody know that
// we finished the MAP phase at this partition
TransactionMapWrapperCallback callback = mr_ts.getTransactionMapWrapperCallback();
assert (callback != null) : "Unexpected null callback for " + mr_ts;
assert (callback.isInitialized()) : "Unexpected uninitalized callback for " + mr_ts;
callback.run(this.partitionId);
}
// ----------------------------------------------------------------------------
// REDUCE PHASE
// ----------------------------------------------------------------------------
else if (mr_ts.isReducePhase()) {
// If this is the local/base partition, send out the start REDUCE message
if (is_local) {
if (debug.val)
LOG.debug("<VoltMapReduceProcedure.run> is executing ..<Reduce>...local!!!....\n");
// Send out network messages to all other partitions to tell them to execute the Reduce phase of this job
hstore_site.getCoordinator().transactionReduce(mr_ts, mr_ts.getTransactionReduceCallback());
}
this.reduce_input = null; //
this.reduce_input = mr_ts.getReduceInputByPartition(this.partitionId);
assert(this.reduce_input != null);
if(debug.val)
LOG.debug(String.format("TXN: %s, [Stage] \n<VoltMapReduceProcedure.run> is executing <Reduce>..",mr_ts));
if (debug.val)
LOG.debug(String.format("<ReduceInputTable> Partition:%d\n %s", this.partitionId,this.reduce_input));
// Sort the the MAP_OUTPUT table
// Build an "smart" iterator that loops through the MAP_OUTPUT table key-by-key
@SuppressWarnings("unchecked")
VoltTable sorted = VoltTableUtil.sort(this.reduce_input, Pair.of(0, SortDirectionType.ASC));
//VoltTable sorted = VoltTableUtil.sort(mr_ts.getReduceInputByPartition(this.partitionId), Pair.of(0, SortDirectionType.ASC));
assert(sorted != null);
if (debug.val)
LOG.debug(String.format("<Sorted_ReduceInputTable> Partition:%d\n %s", this.partitionId,sorted));
this.reduce_output = mr_ts.getReduceOutputByPartition(this.partitionId);
assert(this.reduce_output != null);
// Make a Hstore.PartitionResult
ReduceInputIterator<K> rows = new ReduceInputIterator<K>(sorted);
// Loop over that iterator and call runReduce
if (debug.val)
LOG.debug(String.format("REDUCE: About to process %d records for %s on partition %d",
sorted.getRowCount(), this.mr_ts, this.partitionId));
while (rows.hasNext()) {
K key = rows.getKey();
this.reduce(key, rows);
}
if (debug.val)
LOG.debug(String.format("<ReduceOutputTable> Partition:%d\n %s", this.partitionId,this.reduce_output));
// Loop over that iterator and call runReduce
if (debug.val)
LOG.debug(String.format("REDUCE: %s generated %d results on partition %d",
this.mr_ts, this.reduce_output.getRowCount(), this.partitionId));
ByteString reduceOutData = null;
try {
ByteBuffer b = ByteBuffer.wrap(FastSerializer.serialize(reduce_output));
reduceOutData = ByteString.copyFrom(b.array());
} catch (Exception ex) {
throw new RuntimeException(String.format("Unexpected error when serializing %s reduceOutput data for partition %d",
mr_ts, this.partitionId), ex);
}
ReduceResult.Builder builder = ReduceResult.newBuilder()
.setData(reduceOutData)
.setPartitionId(this.partitionId)
.setStatus(Status.OK);
TransactionReduceWrapperCallback callback = mr_ts.getTransactionReduceWrapperCallback();
assert (callback != null) : "Unexpected null TransactionReduceWrapperCallback for " + mr_ts;
assert (callback.isInitialized()) : "Unexpected uninitalized TransactionReduceWrapperCallback for " + mr_ts;
callback.run(builder.build());
}
return (result);
}