/*
* @(#)AvgResultsExitOperation.java 2012-8-1 下午10:00:00
*
* Copyright (c) 2011-2012 Makersoft.org all rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*
*/
package org.makersoft.shards.strategy.exit.impl;
import java.util.Collections;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.makersoft.shards.strategy.exit.ExitOperation;
import org.makersoft.shards.strategy.exit.ExitOperationUtils;
import org.makersoft.shards.utils.Pair;
/**
*
*/
public class AvgResultsExitOperation implements ExitOperation {
private final Log log = LogFactory.getLog(getClass());
public List<Object> apply(List<Object> results) {
List<Object> nonNullResults = ExitOperationUtils.getNonNullList(results);
Double total = null;
int numResults = 0;
for (Object result : nonNullResults) {
/**
* We expect all entries to be Object arrays. the first entry in the
* array is the average (a double) the second entry in the array is
* the number of rows that were examined to arrive at the average.
*/
Pair<Double, Integer> pair = getResultPair(result);
Double shardAvg = pair.first;
if (shardAvg == null) {
// if there's no result from this shard it doesn't go into the
// calculation. This is consistent with how avg is implemented
// in the database
continue;
}
int shardResults = pair.second;
Double shardTotal = shardAvg * shardResults;
if (total == null) {
total = shardTotal;
} else {
total += shardTotal;
}
numResults += shardResults;
}
if (numResults == 0 || total == null) {
return Collections.singletonList(null);
}
return Collections.<Object>singletonList(total / numResults);
}
private Pair<Double, Integer> getResultPair(Object result) {
if (!(result instanceof Object[])) {
final String msg = "Wrong type in result list. Expected "
+ Object[].class + " but found " + result.getClass();
log.error(msg);
throw new IllegalStateException(msg);
}
Object[] resultArr = (Object[]) result;
if (resultArr.length != 2) {
final String msg = "Result array is wrong size. Expected 2 "
+ " but found " + resultArr.length;
log.error(msg);
throw new IllegalStateException(msg);
}
return Pair.of((Double) resultArr[0], (Integer) resultArr[1]);
}
}