private <R, S, P extends Message, Q extends Message, T extends Message> Pair<List<S>, Long>
    getStdArgs(final Table table, final ColumnInterpreter<R, S, P, Q, T> ci, final Scan scan)
      throws Throwable {
    final AggregateRequest requestArg = validateArgAndGetPB(scan, ci, false, false);
    class StdCallback implements Batch.Callback<Pair<List<S>, Long>> {
      long rowCountVal = 0L;
      S sumVal = null, sumSqVal = null;

      public synchronized Pair<List<S>, Long> getStdParams() {
        List<S> l = new ArrayList<>(2);
        l.add(sumVal);
        l.add(sumSqVal);
        Pair<List<S>, Long> p = new Pair<>(l, rowCountVal);
        return p;
      }

      @Override
      public synchronized void update(byte[] region, byte[] row, Pair<List<S>, Long> result) {
        if (result.getFirst().size() > 0) {
          sumVal = ci.add(sumVal, result.getFirst().get(0));
          sumSqVal = ci.add(sumSqVal, result.getFirst().get(1));
          rowCountVal += result.getSecond();
        }
      }
    }

    StdCallback stdCallback = new StdCallback();
    table.coprocessorService(AggregateService.class, scan.getStartRow(), scan.getStopRow(),
      new Batch.Call<AggregateService, Pair<List<S>, Long>>() {
        @Override
        public Pair<List<S>, Long> call(AggregateService instance) throws IOException {
          RpcController controller = new AggregationClientRpcController();
          CoprocessorRpcUtils.BlockingRpcCallback<AggregateResponse> rpcCallback =
            new CoprocessorRpcUtils.BlockingRpcCallback<>();
          instance.getStd(controller, requestArg, rpcCallback);
          AggregateResponse response = rpcCallback.get();
          if (controller.failed()) {
            throw new IOException(controller.errorText());
          }
          Pair<List<S>, Long> pair = new Pair<>(new ArrayList<>(), 0L);
          if (response.getFirstPartCount() == 0) {
            return pair;
          }
          List<S> list = new ArrayList<>();
          for (int i = 0; i < response.getFirstPartCount(); i++) {
            ByteString b = response.getFirstPart(i);
            T t = getParsedGenericInstance(ci.getClass(), 4, b);
            S s = ci.getPromotedValueFromProto(t);
            list.add(s);
          }
          pair.setFirst(list);
          ByteBuffer bb =
            ByteBuffer.allocate(8).put(getBytesFromResponse(response.getSecondPart()));
          bb.rewind();
          pair.setSecond(bb.getLong());
          return pair;
        }
      }, stdCallback);
    return stdCallback.getStdParams();
  }
It computes a global standard deviation for a given column and its value. Standard deviation is
square root of (average of squares - average*average). From individual regions, it obtains sum,
square sum and number of rows. With these, the above values are computed to get the global std.
@param table table to scan.
@param scan  the HBase scan object to use to read data from HBase
@return standard deviations
@throws Throwable The caller is supposed to handle the exception as they are thrown &amp;
                  propagated to it.
hbase-endpoint/src/main/java/org/apache/hadoop/hbase/client/coprocessor/AggregationClient.java