use of org.apache.rya.api.function.aggregation.AggregationFunction in project incubator-rya by apache.
the class AggregationResultUpdater method updateAggregateResults.
/**
* Updates the results of an Aggregation node where its child has emitted a new Binding Set.
*
* @param tx - The transaction all Fluo queries will use. (not null)
* @param childBindingSet - The Binding Set that was omitted by the Aggregation Node's child. (not null)
* @param aggregationMetadata - The metadata of the Aggregation node whose results will be updated. (not null)
* @throws Exception The update could not be successfully performed.
*/
public void updateAggregateResults(final TransactionBase tx, final VisibilityBindingSet childBindingSet, final AggregationMetadata aggregationMetadata) throws Exception {
requireNonNull(tx);
requireNonNull(childBindingSet);
requireNonNull(aggregationMetadata);
log.trace("Transaction ID: " + tx.getStartTimestamp() + "\n" + "Child Binding Set:\n" + childBindingSet + "\n");
// The Row ID for the Aggregation State that needs to be updated is defined by the Group By variables.
final String aggregationNodeId = aggregationMetadata.getNodeId();
final VariableOrder groupByVars = aggregationMetadata.getGroupByVariableOrder();
final Bytes rowId = makeRowKey(aggregationNodeId, groupByVars, childBindingSet);
// Load the old state from the bytes if one was found; otherwise initialize the state.
final Optional<Bytes> stateBytes = Optional.ofNullable(tx.get(rowId, FluoQueryColumns.AGGREGATION_BINDING_SET));
final AggregationState state;
if (stateBytes.isPresent()) {
// Deserialize the old state
final byte[] bytes = stateBytes.get().toArray();
state = AGG_STATE_SERDE.deserialize(bytes);
} else {
// Initialize a new state.
state = new AggregationState();
// If we have group by bindings, their values need to be added to the state's binding set.
final MapBindingSet bindingSet = state.getBindingSet();
for (final String variable : aggregationMetadata.getGroupByVariableOrder()) {
bindingSet.addBinding(childBindingSet.getBinding(variable));
}
}
log.trace("Transaction ID: " + tx.getStartTimestamp() + "\n" + "Before Update: " + LogUtils.clean(state.getBindingSet().toString()) + "\n");
// Update the visibilities of the result binding set based on the child's visibilities.
final String oldVisibility = state.getVisibility();
final String updateVisibilities = VisibilitySimplifier.unionAndSimplify(oldVisibility, childBindingSet.getVisibility());
state.setVisibility(updateVisibilities);
// Update the Aggregation State with each Aggregation function included within this group.
for (final AggregationElement aggregation : aggregationMetadata.getAggregations()) {
final AggregationType type = aggregation.getAggregationType();
final AggregationFunction function = FUNCTIONS.get(type);
if (function == null) {
throw new RuntimeException("Unrecognized aggregation function: " + type);
}
function.update(aggregation, state, childBindingSet);
}
log.trace("Transaction ID: " + tx.getStartTimestamp() + "\n" + "After Update:" + LogUtils.clean(state.getBindingSet().toString()) + "\n");
// Store the updated state. This will write on top of any old state that was present for the Group By values.
tx.set(rowId, FluoQueryColumns.AGGREGATION_BINDING_SET, Bytes.of(AGG_STATE_SERDE.serialize(state)));
}
Aggregations