mutation_query: to_data_query_result enforces row limit

This patch changes mutation_query::to_data_query_result() so that it
enforces the row limit alongside the partition limit and the
per-partition limit.

In the following patch, we'll enforce the row limit in an upper layer,
but this lets us optimize the case where only when replica replies.

Signed-off-by: Duarte Nunes <duarte@scylladb.com>
This commit is contained in:
Duarte Nunes
2016-12-13 17:41:36 +01:00
parent c2072c7dc9
commit efc986d548
3 changed files with 7 additions and 5 deletions

View File

@@ -57,13 +57,14 @@ bool reconcilable_result::operator!=(const reconcilable_result& other) const {
}
query::result
to_data_query_result(const reconcilable_result& r, schema_ptr s, const query::partition_slice& slice, uint32_t max_partitions) {
to_data_query_result(const reconcilable_result& r, schema_ptr s, const query::partition_slice& slice, uint32_t max_rows, uint32_t max_partitions) {
query::result::builder builder(slice, query::result_request::only_result, { });
for (const partition& p : r.partitions()) {
if (!max_partitions--) {
if (builder.row_count() >= max_rows || builder.partition_count() >= max_partitions) {
break;
}
p.mut().unfreeze(s).query(builder, slice, gc_clock::time_point::min(), query::max_rows);
// Also enforces the per-partition limit.
p.mut().unfreeze(s).query(builder, slice, gc_clock::time_point::min(), max_rows - builder.row_count());
}
if (r.is_short_read()) {
builder.mark_as_short_read();

View File

@@ -105,7 +105,7 @@ public:
printer pretty_printer(schema_ptr) const;
};
query::result to_data_query_result(const reconcilable_result&, schema_ptr, const query::partition_slice&, uint32_t partition_limit = query::max_partitions);
query::result to_data_query_result(const reconcilable_result&, schema_ptr, const query::partition_slice&, uint32_t row_limit, uint32_t partition_limit);
// Performs a query on given data source returning data in reconcilable form.
//

View File

@@ -2346,7 +2346,8 @@ protected:
if (rr_opt && (can_send_short_read || data_resolver->all_reached_end() || rr_opt->row_count() >= original_row_limit()
|| data_resolver->live_partition_count() >= original_partition_limit())
&& !data_resolver->any_partition_short_read()) {
auto result = ::make_foreign(::make_lw_shared(to_data_query_result(std::move(*rr_opt), _schema, _cmd->slice)));
auto result = ::make_foreign(::make_lw_shared(
to_data_query_result(std::move(*rr_opt), _schema, _cmd->slice, _cmd->row_limit, cmd->partition_limit)));
// wait for write to complete before returning result to prevent multiple concurrent read requests to
// trigger repair multiple times and to prevent quorum read to return an old value, even after a quorum
// another read had returned a newer value (but the newer value had not yet been sent to the other replicas)