/** * Counts the rows from the {@code scanner} until exhaustion. It doesn't require the scanner to be * new, so it can be used to finish scanning a previously-started scan. */ protected static int countRowsInScan(AsyncKuduScanner scanner) throws Exception { final AtomicInteger counter = new AtomicInteger(); Callback<Object, RowResultIterator> cb = new Callback<Object, RowResultIterator>() { @Override public Object call(RowResultIterator arg) throws Exception { if (arg == null) return null; counter.addAndGet(arg.getNumRows()); return null; } }; while (scanner.hasMoreRows()) { Deferred<RowResultIterator> data = scanner.nextRows(); data.addCallbacks(cb, defaultErrorCB); data.join(DEFAULT_SLEEP); } Deferred<RowResultIterator> closer = scanner.close(); closer.addCallbacks(cb, defaultErrorCB); closer.join(DEFAULT_SLEEP); return counter.get(); }
/** * Register a callback and an "errback". * * <p>This has the exact same effect as {@link Deferred#addCallbacks(Callback, Callback)} keeps * the type information "correct" when the callback and errback return a {@code Deferred}. * * @param d The {@code Deferred} we want to add the callback and errback to. * @param cb The callback to register. * @param eb The errback to register. * @return {@code d} with an "updated" type. */ @SuppressWarnings("unchecked") public static <T, R, D extends Deferred<R>, E> Deferred<R> addCallbacksDeferring( final Deferred<T> d, final Callback<D, T> cb, final Callback<D, E> eb) { return d.addCallbacks((Callback<R, T>) ((Object) cb), (Callback<R, E>) ((Object) eb)); }