@Override public BigDecimalMsg getProtoForCellType(BigDecimal t) { return getProtoForType(t); }
@Override public synchronized void onRegionComplete(RegionInfo region, AggregateResponse resp) { try { aggregate(region, resp); } catch (IOException e) { completeExceptionally(e); } }
@Override public synchronized void onError(Throwable error) { completeExceptionally(error); }
private void invokeCallBack(byte[] regionName, byte[] row, CResult result) { if (callback != null) { try { //noinspection unchecked // TODO: would callback expect a replica region name if it gets one? this.callback.update(regionName, row, result); } catch (Throwable t) { LOG.error("User callback threw an exception for " + Bytes.toStringBinary(regionName) + ", ignoring", t); } } }
@Test public void testAvg() throws InterruptedException, ExecutionException { assertEquals((COUNT - 1) / 2.0, AsyncAggregationClient .avg(TABLE, new LongColumnInterpreter(), new Scan().addColumn(CF, CQ)).get().doubleValue(), DELTA); }
@Test public void testRowCount() throws InterruptedException, ExecutionException { assertEquals(COUNT, AsyncAggregationClient .rowCount(TABLE, new LongColumnInterpreter(), new Scan().addColumn(CF, CQ)).get() .longValue()); }
@Test public void testSum() throws InterruptedException, ExecutionException { assertEquals(COUNT * (COUNT - 1) / 2, AsyncAggregationClient .sum(TABLE, new LongColumnInterpreter(), new Scan().addColumn(CF, CQ)).get().longValue()); }
@Test public void testMin() throws InterruptedException, ExecutionException { assertEquals(0, AsyncAggregationClient .min(TABLE, new LongColumnInterpreter(), new Scan().addColumn(CF, CQ)).get().longValue()); }
@Test public void testMax() throws InterruptedException, ExecutionException { assertEquals(COUNT - 1, AsyncAggregationClient .max(TABLE, new LongColumnInterpreter(), new Scan().addColumn(CF, CQ)).get().longValue()); }
/** * It computes average while fetching sum and row count from all the * corresponding regions. Approach is to compute a global sum of region level * sum and rowcount and then compute the average. * @param tableName the name of the table to scan * @param scan the HBase scan object to use to read data from HBase * @throws Throwable The caller is supposed to handle the exception as they are thrown * & propagated to it. */ private <R, S, P extends Message, Q extends Message, T extends Message> Pair<S, Long> getAvgArgs( final TableName tableName, final ColumnInterpreter<R, S, P, Q, T> ci, final Scan scan) throws Throwable { try (Table table = connection.getTable(tableName)) { return getAvgArgs(table, ci, scan); } }
/** * It gives the row count, by summing up the individual results obtained from * regions. In case the qualifier is null, FirstKeyValueFilter is used to * optimised the operation. In case qualifier is provided, I can't use the * filter as it may set the flag to skip to next row, but the value read is * not of the given filter: in this case, this particular row will not be * counted ==> an error. * @param tableName the name of the table to scan * @param ci the user's ColumnInterpreter implementation * @param scan the HBase scan object to use to read data from HBase * @return <R, S> * @throws Throwable The caller is supposed to handle the exception as they are thrown * & propagated to it. */ public <R, S, P extends Message, Q extends Message, T extends Message> long rowCount( final TableName tableName, final ColumnInterpreter<R, S, P, Q, T> ci, final Scan scan) throws Throwable { try (Table table = connection.getTable(tableName)) { return rowCount(table, ci, scan); } }
/** * It sums up the value returned from various regions. In case qualifier is * null, summation of all the column qualifiers in the given family is done. * @param tableName the name of the table to scan * @param ci the user's ColumnInterpreter implementation * @param scan the HBase scan object to use to read data from HBase * @return sum <S> * @throws Throwable The caller is supposed to handle the exception as they are thrown * & propagated to it. */ public <R, S, P extends Message, Q extends Message, T extends Message> S sum( final TableName tableName, final ColumnInterpreter<R, S, P, Q, T> ci, final Scan scan) throws Throwable { try (Table table = connection.getTable(tableName)) { return sum(table, ci, scan); } }
/** * This is the client side interface/handler for calling the median method for a * given cf-cq combination. This method collects the necessary parameters * to compute the median and returns the median. * @param tableName the name of the table to scan * @param ci the user's ColumnInterpreter implementation * @param scan the HBase scan object to use to read data from HBase * @return R the median * @throws Throwable The caller is supposed to handle the exception as they are thrown * & propagated to it. */ public <R, S, P extends Message, Q extends Message, T extends Message> R median(final TableName tableName, ColumnInterpreter<R, S, P, Q, T> ci, Scan scan) throws Throwable { try (Table table = connection.getTable(tableName)) { return median(table, ci, scan); } }
/** * It gives the maximum value of a column for a given column family for the * given range. In case qualifier is null, a max of all values for the given * family is returned. * @param tableName the name of the table to scan * @param ci the user's ColumnInterpreter implementation * @param scan the HBase scan object to use to read data from HBase * @return max val <R> * @throws Throwable The caller is supposed to handle the exception as they are thrown * & propagated to it. */ public <R, S, P extends Message, Q extends Message, T extends Message> R max( final TableName tableName, final ColumnInterpreter<R, S, P, Q, T> ci, final Scan scan) throws Throwable { try (Table table = connection.getTable(tableName)) { return max(table, ci, scan); } }
/** * It gives the minimum value of a column for a given column family for the * given range. In case qualifier is null, a min of all values for the given * family is returned. * @param tableName the name of the table to scan * @param ci the user's ColumnInterpreter implementation * @param scan the HBase scan object to use to read data from HBase * @return min val <R> * @throws Throwable The caller is supposed to handle the exception as they are thrown * & propagated to it. */ public <R, S, P extends Message, Q extends Message, T extends Message> R min( final TableName tableName, final ColumnInterpreter<R, S, P, Q, T> ci, final Scan scan) throws Throwable { try (Table table = connection.getTable(tableName)) { return min(table, ci, scan); } }
/** * This is the client side interface/handle for calling the std method for a * given cf-cq combination. It was necessary to add one more call stack as its * return type should be a decimal value, irrespective of what * columninterpreter says. So, this methods collects the necessary parameters * to compute the std and returns the double value. * @param tableName the name of the table to scan * @param ci the user's ColumnInterpreter implementation * @param scan the HBase scan object to use to read data from HBase * @return <R, S> * @throws Throwable The caller is supposed to handle the exception as they are thrown * & propagated to it. */ public <R, S, P extends Message, Q extends Message, T extends Message> double std(final TableName tableName, ColumnInterpreter<R, S, P, Q, T> ci, Scan scan) throws Throwable { try (Table table = connection.getTable(tableName)) { return std(table, ci, scan); } }
@Override public synchronized void onComplete() { if (finished) { return; } finished = true; future.complete(getFinalResult()); } }
private static <R, S, P extends Message, Q extends Message, T extends Message> S getPromotedValueFromProto(ColumnInterpreter<R, S, P, Q, T> ci, AggregateResponse resp, int firstPartIndex) throws IOException { T t = getParsedGenericInstance(ci.getClass(), 4, resp.getFirstPart(firstPartIndex)); return ci.getPromotedValueFromProto(t); }
@Override public BigDecimalMsg getProtoForPromotedType(BigDecimal s) { return getProtoForType(s); }
@Override public synchronized void onRegionError(RegionInfo region, Throwable error) { completeExceptionally(error); }