Как получить количество выбранных строк после использования результирующего набора?

#cassandra #pagination

#cassandra #разбивка на страницы

Вопрос:

Я следовал инструкциям на официальном веб-сайте cassandra, чтобы асинхронно использовать результирующие наборы моих запросов.

 ResultSetFuture future = session.executeAsync("SELECT release_version FROM system.local");
Futures.addCallback(future,
    new FutureCallback<ResultSet>() {
        @Override public void onSuccess(ResultSet result) {
            gui.setMessage("Cassandra version is "   result.one().getString("release_version"));
        }

        @Override public void onFailure(Throwable t) {
            gui.setMessage("Error while reading Cassandra version: "   t.getMessage());
        }
    },
    MoreExecutors.sameThreadExecutor()
);
 

В основном это работает нормально, но для того, чтобы увидеть, сколько строк было извлечено, я обернул свой FutureCallback в LogAwareCallback, который, немного упрощенный, выглядит следующим образом:

 private static final class LogAwareCallback implements FutureCallback<ResultSet> {

    private final FutureCallback<ResultSet> origin;
    private final String query;
    private final Object [] parameters;

    private LogAwareCallback(
            FutureCallback<ResultSet> origin,
            String query,
            Object [] parameters) {
        this.origin = origin;
        this.query = query;
        this.parameters = parameters;   
    }

    @Override
    public void onSuccess(ResultSet rows) {
        origin.onSuccess(rows);

        // as all rows should have been processed at this state,
        // it should be safe to call all with size now
        int resultSize = rows.all().size();
        log(query, parameters, resultSize);             
    }

    @Override
    public void onFailure(Throwable throwable) {
        // FAILURE HANDLING...
    }

    private void log(String query, Object [] parameters, int resultSize) {
        // LOG result size for given query
    }
}
 

Проблема в том, что обернутый FutureCallback уже использовал весь результирующий набор на данный момент времени, и я всегда получаю размер результата 0, хотя было обработано несколько строк.

Таким образом, мой вопрос в том, есть ли способ получить количество возвращенных строк из результирующего набора, даже если оно было полностью использовано?

Ответ №1:

all() возвращает оставшиеся строки и очищает список. Таким образом, вы не сможете легко получить количество обработанных строк. Но есть и альтернатива,

Если вы изменили свой onSuccess в LogAwareCallback на,

 @Override
    public void onSuccess(ResultSet rows) {
        *int resultSize = rows.getAvailableWithoutFetching();*
        log(query, parameters, resultSize); 
        origin.onSuccess(rows);                    
    }
 

вы получите количество строк в результирующем наборе без извлечения дополнительных строк из базы данных. Здесь есть оговорка, что если общее количество строк, ожидаемое в результате запроса, больше размера страницы, вы получите только это (размер страницы) в качестве выходных данных.

Комментарии:

1. Я тоже пробовал это, но это также дало мне 0 ResultSize.

2. вы пробовали это перед вызовом origin.onSuccess(rows); и он все равно дал вам 0? А затем он также напечатал «Версия Cassandra» …?

3. аааа, понятно. Извините, не понял, что вы меняете порядок операторов. Я предполагаю, что getAvailableWithoutFetching — довольно легкая операция?

4. да, я бы так подумал, поскольку он также часто используется при ранней выборке во время разбивки на страницы. Но поскольку я не знаю внутреннего кода драйвера, возможно, вам захочется провести тест перед использованием в производственном коде.

5. вызов O (1). Довольно производительный. Это решило вашу проблему? Спасибо.