protected List<Row> queryNextPage(int pageSize, ConsistencyLevel consistencyLevel, boolean localQuery) throws RequestValidationException, RequestExecutionException { // For some queries, such as a DISTINCT query on static columns, the limit for slice queries will be lower // than the page size (in the static example, it will be 1). We use the min here to ensure we don't fetch // more rows than we're supposed to. See CASSANDRA-8108 for more details. SliceQueryFilter filter = command.filter.withUpdatedCount(Math.min(command.filter.count, pageSize)); if (lastReturned != null) filter = filter.withUpdatedStart(lastReturned, cfm); logger.debug("Querying next page of slice query; new filter: {}", filter); ReadCommand pageCmd = command.withUpdatedFilter(filter); return localQuery ? Collections.singletonList(pageCmd.getRow(Keyspace.open(command.ksName))) : StorageProxy.read(Collections.singletonList(pageCmd), consistencyLevel, cstate); }
@Override public ReadCommand maybeGenerateRetryCommand(RowDataResolver resolver, Row row) { int maxLiveColumns = resolver.getMaxLiveCount(); int count = filter.count; // We generate a retry if at least one node reply with count live columns but after merge we have less // than the total number of column we are interested in (which may be < count on a retry). // So in particular, if no host returned count live columns, we know it's not a short read. if (maxLiveColumns < count) return null; int liveCountInRow = row == null || row.cf == null ? 0 : filter.getLiveCount(row.cf, timestamp); if (liveCountInRow < getOriginalRequestedCount()) { // We asked t (= count) live columns and got l (=liveCountInRow) ones. // From that, we can estimate that on this row, for x requested // columns, only l/t end up live after reconciliation. So for next // round we want to ask x column so that x * (l/t) == t, i.e. x = t^2/l. int retryCount = liveCountInRow == 0 ? count + 1 : ((count * count) / liveCountInRow) + 1; SliceQueryFilter newFilter = filter.withUpdatedCount(retryCount); return new RetriedSliceFromReadCommand(ksName, key, cfName, timestamp, newFilter, getOriginalRequestedCount()); } return null; }