mirror of https://github.com/facebook/rocksdb.git
Eliminate some code duplication in MergeHelper (#12121)
Summary: Pull Request resolved: https://github.com/facebook/rocksdb/pull/12121 The patch eliminates some code duplication by unifying the two sets of `MergeHelper::TimedFullMerge` overloads using variadic templates. It also brings the order of parameters into sync when it comes to the various `TimedFullMerge*` methods. Reviewed By: jaykorean Differential Revision: D51862483 fbshipit-source-id: e3f832a6ff89ba34591451655cf11025d0a0d018
This commit is contained in:
parent
2045fe4693
commit
0ebe1614cb
|
@ -1293,8 +1293,8 @@ bool DBIter::MergeWithNoBaseValue(const Slice& user_key) {
|
||||||
const Status s = MergeHelper::TimedFullMerge(
|
const Status s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
||||||
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
||||||
/* update_num_ops_stats */ true, &saved_value_, &pinned_value_,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
&result_type, /* op_failure_scope */ nullptr);
|
&saved_value_, &pinned_value_, &result_type);
|
||||||
return SetValueAndColumnsFromMergeResult(s, result_type);
|
return SetValueAndColumnsFromMergeResult(s, result_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,8 +1306,8 @@ bool DBIter::MergeWithPlainBaseValue(const Slice& value,
|
||||||
const Status s = MergeHelper::TimedFullMerge(
|
const Status s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key, MergeHelper::kPlainBaseValue, value,
|
merge_operator_, user_key, MergeHelper::kPlainBaseValue, value,
|
||||||
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
||||||
/* update_num_ops_stats */ true, &saved_value_, &pinned_value_,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
&result_type, /* op_failure_scope */ nullptr);
|
&saved_value_, &pinned_value_, &result_type);
|
||||||
return SetValueAndColumnsFromMergeResult(s, result_type);
|
return SetValueAndColumnsFromMergeResult(s, result_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1319,8 +1319,8 @@ bool DBIter::MergeWithWideColumnBaseValue(const Slice& entity,
|
||||||
const Status s = MergeHelper::TimedFullMerge(
|
const Status s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key, MergeHelper::kWideBaseValue, entity,
|
merge_operator_, user_key, MergeHelper::kWideBaseValue, entity,
|
||||||
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
||||||
/* update_num_ops_stats */ true, &saved_value_, &pinned_value_,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
&result_type, /* op_failure_scope */ nullptr);
|
&saved_value_, &pinned_value_, &result_type);
|
||||||
return SetValueAndColumnsFromMergeResult(s, result_type);
|
return SetValueAndColumnsFromMergeResult(s, result_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1061,8 +1061,8 @@ static bool SaveValue(void* arg, const char* entry) {
|
||||||
merge_operator, s->key->user_key(),
|
merge_operator, s->key->user_key(),
|
||||||
MergeHelper::kPlainBaseValue, v, merge_context->GetOperands(),
|
MergeHelper::kPlainBaseValue, v, merge_context->GetOperands(),
|
||||||
s->logger, s->statistics, s->clock,
|
s->logger, s->statistics, s->clock,
|
||||||
/* update_num_ops_stats */ true, s->value, s->columns,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
/* op_failure_scope */ nullptr);
|
s->value, s->columns);
|
||||||
}
|
}
|
||||||
} else if (s->value) {
|
} else if (s->value) {
|
||||||
s->value->assign(v.data(), v.size());
|
s->value->assign(v.data(), v.size());
|
||||||
|
@ -1114,8 +1114,8 @@ static bool SaveValue(void* arg, const char* entry) {
|
||||||
*(s->status) = MergeHelper::TimedFullMerge(
|
*(s->status) = MergeHelper::TimedFullMerge(
|
||||||
merge_operator, s->key->user_key(), MergeHelper::kWideBaseValue,
|
merge_operator, s->key->user_key(), MergeHelper::kWideBaseValue,
|
||||||
v, merge_context->GetOperands(), s->logger, s->statistics,
|
v, merge_context->GetOperands(), s->logger, s->statistics,
|
||||||
s->clock, /* update_num_ops_stats */ true, s->value, s->columns,
|
s->clock, /* update_num_ops_stats */ true,
|
||||||
/* op_failure_scope */ nullptr);
|
/* op_failure_scope */ nullptr, s->value, s->columns);
|
||||||
}
|
}
|
||||||
} else if (s->value) {
|
} else if (s->value) {
|
||||||
Slice value_of_default;
|
Slice value_of_default;
|
||||||
|
@ -1152,8 +1152,8 @@ static bool SaveValue(void* arg, const char* entry) {
|
||||||
*(s->status) = MergeHelper::TimedFullMerge(
|
*(s->status) = MergeHelper::TimedFullMerge(
|
||||||
merge_operator, s->key->user_key(), MergeHelper::kNoBaseValue,
|
merge_operator, s->key->user_key(), MergeHelper::kNoBaseValue,
|
||||||
merge_context->GetOperands(), s->logger, s->statistics,
|
merge_context->GetOperands(), s->logger, s->statistics,
|
||||||
s->clock, /* update_num_ops_stats */ true, s->value, s->columns,
|
s->clock, /* update_num_ops_stats */ true,
|
||||||
/* op_failure_scope */ nullptr);
|
/* op_failure_scope */ nullptr, s->value, s->columns);
|
||||||
} else {
|
} else {
|
||||||
// We have found a final value (a base deletion) and have newer
|
// We have found a final value (a base deletion) and have newer
|
||||||
// merge operands that we do not intend to merge. Nothing remains
|
// merge operands that we do not intend to merge. Nothing remains
|
||||||
|
@ -1192,8 +1192,8 @@ static bool SaveValue(void* arg, const char* entry) {
|
||||||
*(s->status) = MergeHelper::TimedFullMerge(
|
*(s->status) = MergeHelper::TimedFullMerge(
|
||||||
merge_operator, s->key->user_key(), MergeHelper::kNoBaseValue,
|
merge_operator, s->key->user_key(), MergeHelper::kNoBaseValue,
|
||||||
merge_context->GetOperands(), s->logger, s->statistics,
|
merge_context->GetOperands(), s->logger, s->statistics,
|
||||||
s->clock, /* update_num_ops_stats */ true, s->value, s->columns,
|
s->clock, /* update_num_ops_stats */ true,
|
||||||
/* op_failure_scope */ nullptr);
|
/* op_failure_scope */ nullptr, s->value, s->columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
*(s->found_final_value) = true;
|
*(s->found_final_value) = true;
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "db/blob/prefetch_buffer_collection.h"
|
#include "db/blob/prefetch_buffer_collection.h"
|
||||||
#include "db/compaction/compaction_iteration_stats.h"
|
#include "db/compaction/compaction_iteration_stats.h"
|
||||||
#include "db/dbformat.h"
|
#include "db/dbformat.h"
|
||||||
#include "db/wide/wide_column_serialization.h"
|
|
||||||
#include "db/wide/wide_columns_helper.h"
|
#include "db/wide/wide_columns_helper.h"
|
||||||
#include "logging/logging.h"
|
#include "logging/logging.h"
|
||||||
#include "monitoring/perf_context_imp.h"
|
#include "monitoring/perf_context_imp.h"
|
||||||
|
@ -111,9 +110,9 @@ Status MergeHelper::TimedFullMergeImpl(
|
||||||
const MergeOperator* merge_operator, const Slice& key,
|
const MergeOperator* merge_operator, const Slice& key,
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_value,
|
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_value,
|
||||||
const std::vector<Slice>& operands, Logger* logger, Statistics* statistics,
|
const std::vector<Slice>& operands, Logger* logger, Statistics* statistics,
|
||||||
SystemClock* clock, bool update_num_ops_stats, std::string* result,
|
SystemClock* clock, bool update_num_ops_stats,
|
||||||
Slice* result_operand, ValueType* result_type,
|
MergeOperator::OpFailureScope* op_failure_scope, std::string* result,
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
Slice* result_operand, ValueType* result_type) {
|
||||||
assert(result);
|
assert(result);
|
||||||
assert(result_type);
|
assert(result_type);
|
||||||
|
|
||||||
|
@ -173,9 +172,9 @@ Status MergeHelper::TimedFullMergeImpl(
|
||||||
const MergeOperator* merge_operator, const Slice& key,
|
const MergeOperator* merge_operator, const Slice& key,
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_value,
|
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_value,
|
||||||
const std::vector<Slice>& operands, Logger* logger, Statistics* statistics,
|
const std::vector<Slice>& operands, Logger* logger, Statistics* statistics,
|
||||||
SystemClock* clock, bool update_num_ops_stats, std::string* result_value,
|
SystemClock* clock, bool update_num_ops_stats,
|
||||||
PinnableWideColumns* result_entity,
|
MergeOperator::OpFailureScope* op_failure_scope, std::string* result_value,
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
PinnableWideColumns* result_entity) {
|
||||||
assert(result_value || result_entity);
|
assert(result_value || result_entity);
|
||||||
assert(!result_value || !result_entity);
|
assert(!result_value || !result_entity);
|
||||||
|
|
||||||
|
@ -245,141 +244,6 @@ Status MergeHelper::TimedFullMergeImpl(
|
||||||
op_failure_scope, std::move(visitor));
|
op_failure_scope, std::move(visitor));
|
||||||
}
|
}
|
||||||
|
|
||||||
Status MergeHelper::TimedFullMerge(
|
|
||||||
const MergeOperator* merge_operator, const Slice& key, NoBaseValueTag,
|
|
||||||
const std::vector<Slice>& operands, Logger* logger, Statistics* statistics,
|
|
||||||
SystemClock* clock, bool update_num_ops_stats, std::string* result,
|
|
||||||
Slice* result_operand, ValueType* result_type,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value;
|
|
||||||
|
|
||||||
return TimedFullMergeImpl(merge_operator, key, std::move(existing_value),
|
|
||||||
operands, logger, statistics, clock,
|
|
||||||
update_num_ops_stats, result, result_operand,
|
|
||||||
result_type, op_failure_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status MergeHelper::TimedFullMerge(
|
|
||||||
const MergeOperator* merge_operator, const Slice& key, PlainBaseValueTag,
|
|
||||||
const Slice& value, const std::vector<Slice>& operands, Logger* logger,
|
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
|
||||||
std::string* result, Slice* result_operand, ValueType* result_type,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value(value);
|
|
||||||
|
|
||||||
return TimedFullMergeImpl(merge_operator, key, std::move(existing_value),
|
|
||||||
operands, logger, statistics, clock,
|
|
||||||
update_num_ops_stats, result, result_operand,
|
|
||||||
result_type, op_failure_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status MergeHelper::TimedFullMerge(
|
|
||||||
const MergeOperator* merge_operator, const Slice& key, WideBaseValueTag,
|
|
||||||
const Slice& entity, const std::vector<Slice>& operands, Logger* logger,
|
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
|
||||||
std::string* result, Slice* result_operand, ValueType* result_type,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value;
|
|
||||||
|
|
||||||
Slice entity_copy(entity);
|
|
||||||
WideColumns existing_columns;
|
|
||||||
|
|
||||||
const Status s =
|
|
||||||
WideColumnSerialization::Deserialize(entity_copy, existing_columns);
|
|
||||||
if (!s.ok()) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
existing_value = std::move(existing_columns);
|
|
||||||
|
|
||||||
return TimedFullMergeImpl(merge_operator, key, std::move(existing_value),
|
|
||||||
operands, logger, statistics, clock,
|
|
||||||
update_num_ops_stats, result, result_operand,
|
|
||||||
result_type, op_failure_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status MergeHelper::TimedFullMerge(
|
|
||||||
const MergeOperator* merge_operator, const Slice& key, WideBaseValueTag,
|
|
||||||
const WideColumns& columns, const std::vector<Slice>& operands,
|
|
||||||
Logger* logger, Statistics* statistics, SystemClock* clock,
|
|
||||||
bool update_num_ops_stats, std::string* result, Slice* result_operand,
|
|
||||||
ValueType* result_type, MergeOperator::OpFailureScope* op_failure_scope) {
|
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value(columns);
|
|
||||||
|
|
||||||
return TimedFullMergeImpl(merge_operator, key, std::move(existing_value),
|
|
||||||
operands, logger, statistics, clock,
|
|
||||||
update_num_ops_stats, result, result_operand,
|
|
||||||
result_type, op_failure_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status MergeHelper::TimedFullMerge(
|
|
||||||
const MergeOperator* merge_operator, const Slice& key, NoBaseValueTag,
|
|
||||||
const std::vector<Slice>& operands, Logger* logger, Statistics* statistics,
|
|
||||||
SystemClock* clock, bool update_num_ops_stats, std::string* result_value,
|
|
||||||
PinnableWideColumns* result_entity,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value;
|
|
||||||
|
|
||||||
return TimedFullMergeImpl(merge_operator, key, std::move(existing_value),
|
|
||||||
operands, logger, statistics, clock,
|
|
||||||
update_num_ops_stats, result_value, result_entity,
|
|
||||||
op_failure_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status MergeHelper::TimedFullMerge(
|
|
||||||
const MergeOperator* merge_operator, const Slice& key, PlainBaseValueTag,
|
|
||||||
const Slice& value, const std::vector<Slice>& operands, Logger* logger,
|
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
|
||||||
std::string* result_value, PinnableWideColumns* result_entity,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value(value);
|
|
||||||
|
|
||||||
return TimedFullMergeImpl(merge_operator, key, std::move(existing_value),
|
|
||||||
operands, logger, statistics, clock,
|
|
||||||
update_num_ops_stats, result_value, result_entity,
|
|
||||||
op_failure_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status MergeHelper::TimedFullMerge(
|
|
||||||
const MergeOperator* merge_operator, const Slice& key, WideBaseValueTag,
|
|
||||||
const Slice& entity, const std::vector<Slice>& operands, Logger* logger,
|
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
|
||||||
std::string* result_value, PinnableWideColumns* result_entity,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value;
|
|
||||||
|
|
||||||
Slice entity_copy(entity);
|
|
||||||
WideColumns existing_columns;
|
|
||||||
|
|
||||||
const Status s =
|
|
||||||
WideColumnSerialization::Deserialize(entity_copy, existing_columns);
|
|
||||||
if (!s.ok()) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
existing_value = std::move(existing_columns);
|
|
||||||
|
|
||||||
return TimedFullMergeImpl(merge_operator, key, std::move(existing_value),
|
|
||||||
operands, logger, statistics, clock,
|
|
||||||
update_num_ops_stats, result_value, result_entity,
|
|
||||||
op_failure_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status MergeHelper::TimedFullMerge(
|
|
||||||
const MergeOperator* merge_operator, const Slice& key, WideBaseValueTag,
|
|
||||||
const WideColumns& columns, const std::vector<Slice>& operands,
|
|
||||||
Logger* logger, Statistics* statistics, SystemClock* clock,
|
|
||||||
bool update_num_ops_stats, std::string* result_value,
|
|
||||||
PinnableWideColumns* result_entity,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope) {
|
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value(columns);
|
|
||||||
|
|
||||||
return TimedFullMergeImpl(merge_operator, key, std::move(existing_value),
|
|
||||||
operands, logger, statistics, clock,
|
|
||||||
update_num_ops_stats, result_value, result_entity,
|
|
||||||
op_failure_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRE: iter points to the first merge type entry
|
// PRE: iter points to the first merge type entry
|
||||||
// POST: iter points to the first entry beyond the merge process (or the end)
|
// POST: iter points to the first entry beyond the merge process (or the end)
|
||||||
// keys_, operands_ are updated to reflect the merge result.
|
// keys_, operands_ are updated to reflect the merge result.
|
||||||
|
@ -519,14 +383,14 @@ Status MergeHelper::MergeUntil(InternalIterator* iter,
|
||||||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kNoBaseValue,
|
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kNoBaseValue,
|
||||||
merge_context_.GetOperands(), logger_, stats_,
|
merge_context_.GetOperands(), logger_, stats_,
|
||||||
clock_, /* update_num_ops_stats */ false,
|
clock_, /* update_num_ops_stats */ false,
|
||||||
&merge_result, /* result_operand */ nullptr,
|
&op_failure_scope, &merge_result,
|
||||||
&merge_result_type, &op_failure_scope);
|
/* result_operand */ nullptr, &merge_result_type);
|
||||||
} else if (ikey.type == kTypeValue) {
|
} else if (ikey.type == kTypeValue) {
|
||||||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kPlainBaseValue,
|
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kPlainBaseValue,
|
||||||
iter->value(), merge_context_.GetOperands(), logger_,
|
iter->value(), merge_context_.GetOperands(), logger_,
|
||||||
stats_, clock_, /* update_num_ops_stats */ false,
|
stats_, clock_, /* update_num_ops_stats */ false,
|
||||||
&merge_result, /* result_operand */ nullptr,
|
&op_failure_scope, &merge_result,
|
||||||
&merge_result_type, &op_failure_scope);
|
/* result_operand */ nullptr, &merge_result_type);
|
||||||
} else if (ikey.type == kTypeBlobIndex) {
|
} else if (ikey.type == kTypeBlobIndex) {
|
||||||
BlobIndex blob_index;
|
BlobIndex blob_index;
|
||||||
|
|
||||||
|
@ -559,20 +423,20 @@ Status MergeHelper::MergeUntil(InternalIterator* iter,
|
||||||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kPlainBaseValue,
|
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kPlainBaseValue,
|
||||||
blob_value, merge_context_.GetOperands(), logger_,
|
blob_value, merge_context_.GetOperands(), logger_,
|
||||||
stats_, clock_, /* update_num_ops_stats */ false,
|
stats_, clock_, /* update_num_ops_stats */ false,
|
||||||
&merge_result, /* result_operand */ nullptr,
|
&op_failure_scope, &merge_result,
|
||||||
&merge_result_type, &op_failure_scope);
|
/* result_operand */ nullptr, &merge_result_type);
|
||||||
} else if (ikey.type == kTypeWideColumnEntity) {
|
} else if (ikey.type == kTypeWideColumnEntity) {
|
||||||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kWideBaseValue,
|
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kWideBaseValue,
|
||||||
iter->value(), merge_context_.GetOperands(), logger_,
|
iter->value(), merge_context_.GetOperands(), logger_,
|
||||||
stats_, clock_, /* update_num_ops_stats */ false,
|
stats_, clock_, /* update_num_ops_stats */ false,
|
||||||
&merge_result, /* result_operand */ nullptr,
|
&op_failure_scope, &merge_result,
|
||||||
&merge_result_type, &op_failure_scope);
|
/* result_operand */ nullptr, &merge_result_type);
|
||||||
} else {
|
} else {
|
||||||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kNoBaseValue,
|
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kNoBaseValue,
|
||||||
merge_context_.GetOperands(), logger_, stats_,
|
merge_context_.GetOperands(), logger_, stats_,
|
||||||
clock_, /* update_num_ops_stats */ false,
|
clock_, /* update_num_ops_stats */ false,
|
||||||
&merge_result, /* result_operand */ nullptr,
|
&op_failure_scope, &merge_result,
|
||||||
&merge_result_type, &op_failure_scope);
|
/* result_operand */ nullptr, &merge_result_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We store the result in keys_.back() and operands_.back()
|
// We store the result in keys_.back() and operands_.back()
|
||||||
|
@ -714,9 +578,9 @@ Status MergeHelper::MergeUntil(InternalIterator* iter,
|
||||||
MergeOperator::OpFailureScope op_failure_scope;
|
MergeOperator::OpFailureScope op_failure_scope;
|
||||||
s = TimedFullMerge(user_merge_operator_, orig_ikey.user_key, kNoBaseValue,
|
s = TimedFullMerge(user_merge_operator_, orig_ikey.user_key, kNoBaseValue,
|
||||||
merge_context_.GetOperands(), logger_, stats_, clock_,
|
merge_context_.GetOperands(), logger_, stats_, clock_,
|
||||||
/* update_num_ops_stats */ false, &merge_result,
|
/* update_num_ops_stats */ false, &op_failure_scope,
|
||||||
/* result_operand */ nullptr, &merge_result_type,
|
&merge_result,
|
||||||
&op_failure_scope);
|
/* result_operand */ nullptr, &merge_result_type);
|
||||||
if (s.ok()) {
|
if (s.ok()) {
|
||||||
// The original key encountered
|
// The original key encountered
|
||||||
// We are certain that keys_ is not empty here (see assertions couple of
|
// We are certain that keys_ is not empty here (see assertions couple of
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "db/merge_context.h"
|
#include "db/merge_context.h"
|
||||||
#include "db/range_del_aggregator.h"
|
#include "db/range_del_aggregator.h"
|
||||||
#include "db/snapshot_checker.h"
|
#include "db/snapshot_checker.h"
|
||||||
|
#include "db/wide/wide_column_serialization.h"
|
||||||
#include "rocksdb/compaction_filter.h"
|
#include "rocksdb/compaction_filter.h"
|
||||||
#include "rocksdb/env.h"
|
#include "rocksdb/env.h"
|
||||||
#include "rocksdb/merge_operator.h"
|
#include "rocksdb/merge_operator.h"
|
||||||
|
@ -60,74 +61,73 @@ class MergeHelper {
|
||||||
struct WideBaseValueTag {};
|
struct WideBaseValueTag {};
|
||||||
static constexpr WideBaseValueTag kWideBaseValue{};
|
static constexpr WideBaseValueTag kWideBaseValue{};
|
||||||
|
|
||||||
// Variants that expose the merge result directly (in serialized form for wide
|
template <typename... ResultTs>
|
||||||
// columns) as well as its value type. Used by iterator and compaction.
|
|
||||||
static Status TimedFullMerge(const MergeOperator* merge_operator,
|
static Status TimedFullMerge(const MergeOperator* merge_operator,
|
||||||
const Slice& key, NoBaseValueTag,
|
const Slice& key, NoBaseValueTag,
|
||||||
const std::vector<Slice>& operands,
|
const std::vector<Slice>& operands,
|
||||||
Logger* logger, Statistics* statistics,
|
Logger* logger, Statistics* statistics,
|
||||||
SystemClock* clock, bool update_num_ops_stats,
|
SystemClock* clock, bool update_num_ops_stats,
|
||||||
std::string* result, Slice* result_operand,
|
MergeOperator::OpFailureScope* op_failure_scope,
|
||||||
ValueType* result_type,
|
ResultTs... results) {
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
MergeOperator::MergeOperationInputV3::ExistingValue existing_value;
|
||||||
|
|
||||||
|
return TimedFullMergeImpl(
|
||||||
|
merge_operator, key, std::move(existing_value), operands, logger,
|
||||||
|
statistics, clock, update_num_ops_stats, op_failure_scope, results...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... ResultTs>
|
||||||
static Status TimedFullMerge(
|
static Status TimedFullMerge(
|
||||||
const MergeOperator* merge_operator, const Slice& key, PlainBaseValueTag,
|
const MergeOperator* merge_operator, const Slice& key, PlainBaseValueTag,
|
||||||
const Slice& value, const std::vector<Slice>& operands, Logger* logger,
|
const Slice& value, const std::vector<Slice>& operands, Logger* logger,
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
||||||
std::string* result, Slice* result_operand, ValueType* result_type,
|
MergeOperator::OpFailureScope* op_failure_scope, ResultTs... results) {
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
MergeOperator::MergeOperationInputV3::ExistingValue existing_value(value);
|
||||||
|
|
||||||
|
return TimedFullMergeImpl(
|
||||||
|
merge_operator, key, std::move(existing_value), operands, logger,
|
||||||
|
statistics, clock, update_num_ops_stats, op_failure_scope, results...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... ResultTs>
|
||||||
static Status TimedFullMerge(
|
static Status TimedFullMerge(
|
||||||
const MergeOperator* merge_operator, const Slice& key, WideBaseValueTag,
|
const MergeOperator* merge_operator, const Slice& key, WideBaseValueTag,
|
||||||
const Slice& entity, const std::vector<Slice>& operands, Logger* logger,
|
const Slice& entity, const std::vector<Slice>& operands, Logger* logger,
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
||||||
std::string* result, Slice* result_operand, ValueType* result_type,
|
MergeOperator::OpFailureScope* op_failure_scope, ResultTs... results) {
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
MergeOperator::MergeOperationInputV3::ExistingValue existing_value;
|
||||||
|
|
||||||
static Status TimedFullMerge(
|
Slice entity_copy(entity);
|
||||||
const MergeOperator* merge_operator, const Slice& key, WideBaseValueTag,
|
WideColumns existing_columns;
|
||||||
const WideColumns& columns, const std::vector<Slice>& operands,
|
|
||||||
Logger* logger, Statistics* statistics, SystemClock* clock,
|
|
||||||
bool update_num_ops_stats, std::string* result, Slice* result_operand,
|
|
||||||
ValueType* result_type, MergeOperator::OpFailureScope* op_failure_scope);
|
|
||||||
|
|
||||||
// Variants that expose the merge result translated to the form requested by
|
const Status s =
|
||||||
// the client. (For example, if the result is a wide-column structure but the
|
WideColumnSerialization::Deserialize(entity_copy, existing_columns);
|
||||||
// client requested the results in plain-value form, the value of the default
|
if (!s.ok()) {
|
||||||
// column is returned.) Used by point lookups.
|
return s;
|
||||||
static Status TimedFullMerge(const MergeOperator* merge_operator,
|
}
|
||||||
const Slice& key, NoBaseValueTag,
|
|
||||||
const std::vector<Slice>& operands,
|
|
||||||
Logger* logger, Statistics* statistics,
|
|
||||||
SystemClock* clock, bool update_num_ops_stats,
|
|
||||||
std::string* result_value,
|
|
||||||
PinnableWideColumns* result_entity,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
|
||||||
|
|
||||||
static Status TimedFullMerge(
|
existing_value = std::move(existing_columns);
|
||||||
const MergeOperator* merge_operator, const Slice& key, PlainBaseValueTag,
|
|
||||||
const Slice& value, const std::vector<Slice>& operands, Logger* logger,
|
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
|
||||||
std::string* result_value, PinnableWideColumns* result_entity,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
|
||||||
|
|
||||||
static Status TimedFullMerge(
|
return TimedFullMergeImpl(
|
||||||
const MergeOperator* merge_operator, const Slice& key, WideBaseValueTag,
|
merge_operator, key, std::move(existing_value), operands, logger,
|
||||||
const Slice& entity, const std::vector<Slice>& operands, Logger* logger,
|
statistics, clock, update_num_ops_stats, op_failure_scope, results...);
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
}
|
||||||
std::string* result_value, PinnableWideColumns* result_entity,
|
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
|
||||||
|
|
||||||
|
template <typename... ResultTs>
|
||||||
static Status TimedFullMerge(const MergeOperator* merge_operator,
|
static Status TimedFullMerge(const MergeOperator* merge_operator,
|
||||||
const Slice& key, WideBaseValueTag,
|
const Slice& key, WideBaseValueTag,
|
||||||
const WideColumns& columns,
|
const WideColumns& columns,
|
||||||
const std::vector<Slice>& operands,
|
const std::vector<Slice>& operands,
|
||||||
Logger* logger, Statistics* statistics,
|
Logger* logger, Statistics* statistics,
|
||||||
SystemClock* clock, bool update_num_ops_stats,
|
SystemClock* clock, bool update_num_ops_stats,
|
||||||
std::string* result_value,
|
MergeOperator::OpFailureScope* op_failure_scope,
|
||||||
PinnableWideColumns* result_entity,
|
ResultTs... results) {
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
MergeOperator::MergeOperationInputV3::ExistingValue existing_value(columns);
|
||||||
|
|
||||||
|
return TimedFullMergeImpl(
|
||||||
|
merge_operator, key, std::move(existing_value), operands, logger,
|
||||||
|
statistics, clock, update_num_ops_stats, op_failure_scope, results...);
|
||||||
|
}
|
||||||
|
|
||||||
// During compaction, merge entries until we hit
|
// During compaction, merge entries until we hit
|
||||||
// - a corrupted key
|
// - a corrupted key
|
||||||
|
@ -271,21 +271,27 @@ class MergeHelper {
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
||||||
MergeOperator::OpFailureScope* op_failure_scope, Visitor&& visitor);
|
MergeOperator::OpFailureScope* op_failure_scope, Visitor&& visitor);
|
||||||
|
|
||||||
|
// Variant that exposes the merge result directly (in serialized form for wide
|
||||||
|
// columns) as well as its value type. Used by iterator and compaction.
|
||||||
static Status TimedFullMergeImpl(
|
static Status TimedFullMergeImpl(
|
||||||
const MergeOperator* merge_operator, const Slice& key,
|
const MergeOperator* merge_operator, const Slice& key,
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_value,
|
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_value,
|
||||||
const std::vector<Slice>& operands, Logger* logger,
|
const std::vector<Slice>& operands, Logger* logger,
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
||||||
std::string* result, Slice* result_operand, ValueType* result_type,
|
MergeOperator::OpFailureScope* op_failure_scope, std::string* result,
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
Slice* result_operand, ValueType* result_type);
|
||||||
|
|
||||||
|
// Variant that exposes the merge result translated into the form requested by
|
||||||
|
// the client. (For example, if the result is a wide-column structure but the
|
||||||
|
// client requested the results in plain-value form, the value of the default
|
||||||
|
// column is returned.) Used by point lookups.
|
||||||
static Status TimedFullMergeImpl(
|
static Status TimedFullMergeImpl(
|
||||||
const MergeOperator* merge_operator, const Slice& key,
|
const MergeOperator* merge_operator, const Slice& key,
|
||||||
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_value,
|
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_value,
|
||||||
const std::vector<Slice>& operands, Logger* logger,
|
const std::vector<Slice>& operands, Logger* logger,
|
||||||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
||||||
std::string* result_value, PinnableWideColumns* result_entity,
|
MergeOperator::OpFailureScope* op_failure_scope,
|
||||||
MergeOperator::OpFailureScope* op_failure_scope);
|
std::string* result_value, PinnableWideColumns* result_entity);
|
||||||
};
|
};
|
||||||
|
|
||||||
// MergeOutputIterator can be used to iterate over the result of a merge.
|
// MergeOutputIterator can be used to iterate over the result of a merge.
|
||||||
|
|
|
@ -2536,8 +2536,8 @@ void Version::Get(const ReadOptions& read_options, const LookupKey& k,
|
||||||
*status = MergeHelper::TimedFullMerge(
|
*status = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
||||||
merge_context->GetOperands(), info_log_, db_statistics_, clock_,
|
merge_context->GetOperands(), info_log_, db_statistics_, clock_,
|
||||||
/* update_num_ops_stats */ true, value ? value->GetSelf() : nullptr,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
columns, /* op_failure_scope */ nullptr);
|
value ? value->GetSelf() : nullptr, columns);
|
||||||
if (status->ok()) {
|
if (status->ok()) {
|
||||||
if (LIKELY(value != nullptr)) {
|
if (LIKELY(value != nullptr)) {
|
||||||
value->PinSelf();
|
value->PinSelf();
|
||||||
|
@ -2782,9 +2782,8 @@ void Version::MultiGet(const ReadOptions& read_options, MultiGetRange* range,
|
||||||
*status = MergeHelper::TimedFullMerge(
|
*status = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
||||||
iter->merge_context.GetOperands(), info_log_, db_statistics_, clock_,
|
iter->merge_context.GetOperands(), info_log_, db_statistics_, clock_,
|
||||||
/* update_num_ops_stats */ true,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
iter->value ? iter->value->GetSelf() : nullptr, iter->columns,
|
iter->value ? iter->value->GetSelf() : nullptr, iter->columns);
|
||||||
/* op_failure_scope */ nullptr);
|
|
||||||
if (LIKELY(iter->value != nullptr)) {
|
if (LIKELY(iter->value != nullptr)) {
|
||||||
iter->value->PinSelf();
|
iter->value->PinSelf();
|
||||||
range->AddValueSize(iter->value->size());
|
range->AddValueSize(iter->value->size());
|
||||||
|
|
|
@ -2545,9 +2545,8 @@ class MemTableInserter : public WriteBatch::Handler {
|
||||||
WideColumnsHelper::GetDefaultColumn(columns), {value},
|
WideColumnsHelper::GetDefaultColumn(columns), {value},
|
||||||
moptions->info_log, moptions->statistics,
|
moptions->info_log, moptions->statistics,
|
||||||
SystemClock::Default().get(),
|
SystemClock::Default().get(),
|
||||||
/* update_num_ops_stats */ false, &new_value,
|
/* update_num_ops_stats */ false, /* op_failure_scope */ nullptr,
|
||||||
/* result_operand */ nullptr, &new_value_type,
|
&new_value, /* result_operand */ nullptr, &new_value_type);
|
||||||
/* op_failure_scope */ nullptr);
|
|
||||||
} else {
|
} else {
|
||||||
// `op_failure_scope` (an output parameter) is not provided (set to
|
// `op_failure_scope` (an output parameter) is not provided (set to
|
||||||
// nullptr) since a failure must be propagated regardless of its
|
// nullptr) since a failure must be propagated regardless of its
|
||||||
|
@ -2556,9 +2555,8 @@ class MemTableInserter : public WriteBatch::Handler {
|
||||||
merge_operator, key, MergeHelper::kWideBaseValue, columns,
|
merge_operator, key, MergeHelper::kWideBaseValue, columns,
|
||||||
{value}, moptions->info_log, moptions->statistics,
|
{value}, moptions->info_log, moptions->statistics,
|
||||||
SystemClock::Default().get(),
|
SystemClock::Default().get(),
|
||||||
/* update_num_ops_stats */ false, &new_value,
|
/* update_num_ops_stats */ false, /* op_failure_scope */ nullptr,
|
||||||
/* result_operand */ nullptr, &new_value_type,
|
&new_value, /* result_operand */ nullptr, &new_value_type);
|
||||||
/* op_failure_scope */ nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!merge_status.ok()) {
|
if (!merge_status.ok()) {
|
||||||
|
|
|
@ -232,7 +232,6 @@ bool GetContext::SaveValue(const ParsedInternalKey& parsed_key,
|
||||||
return true; // to continue to the next seq
|
return true; // to continue to the next seq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (seq_ != nullptr) {
|
if (seq_ != nullptr) {
|
||||||
// Set the sequence number if it is uninitialized
|
// Set the sequence number if it is uninitialized
|
||||||
if (*seq_ == kMaxSequenceNumber) {
|
if (*seq_ == kMaxSequenceNumber) {
|
||||||
|
@ -496,9 +495,8 @@ void GetContext::MergeWithNoBaseValue() {
|
||||||
const Status s = MergeHelper::TimedFullMerge(
|
const Status s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key_, MergeHelper::kNoBaseValue,
|
merge_operator_, user_key_, MergeHelper::kNoBaseValue,
|
||||||
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
||||||
/* update_num_ops_stats */ true,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_,
|
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_);
|
||||||
/* op_failure_scope */ nullptr);
|
|
||||||
PostprocessMerge(s);
|
PostprocessMerge(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,9 +510,8 @@ void GetContext::MergeWithPlainBaseValue(const Slice& value) {
|
||||||
const Status s = MergeHelper::TimedFullMerge(
|
const Status s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key_, MergeHelper::kPlainBaseValue, value,
|
merge_operator_, user_key_, MergeHelper::kPlainBaseValue, value,
|
||||||
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
||||||
/* update_num_ops_stats */ true,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_,
|
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_);
|
||||||
/* op_failure_scope */ nullptr);
|
|
||||||
PostprocessMerge(s);
|
PostprocessMerge(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,9 +525,8 @@ void GetContext::MergeWithWideColumnBaseValue(const Slice& entity) {
|
||||||
const Status s = MergeHelper::TimedFullMerge(
|
const Status s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key_, MergeHelper::kWideBaseValue, entity,
|
merge_operator_, user_key_, MergeHelper::kWideBaseValue, entity,
|
||||||
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
||||||
/* update_num_ops_stats */ true,
|
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_,
|
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_);
|
||||||
/* op_failure_scope */ nullptr);
|
|
||||||
PostprocessMerge(s);
|
PostprocessMerge(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -408,8 +408,8 @@ class WriteBatchWithIndexInternal {
|
||||||
return MergeHelper::TimedFullMerge(
|
return MergeHelper::TimedFullMerge(
|
||||||
ioptions->merge_operator.get(), key, MergeHelper::kNoBaseValue,
|
ioptions->merge_operator.get(), key, MergeHelper::kNoBaseValue,
|
||||||
context.GetOperands(), ioptions->logger, ioptions->stats,
|
context.GetOperands(), ioptions->logger, ioptions->stats,
|
||||||
ioptions->clock, /* update_num_ops_stats */ false, results...,
|
ioptions->clock, /* update_num_ops_stats */ false,
|
||||||
/* op_failure_scope */ nullptr);
|
/* op_failure_scope */ nullptr, results...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BaseTag, typename BaseT, typename... ResultTs>
|
template <typename BaseTag, typename BaseT, typename... ResultTs>
|
||||||
|
@ -432,8 +432,8 @@ class WriteBatchWithIndexInternal {
|
||||||
return MergeHelper::TimedFullMerge(
|
return MergeHelper::TimedFullMerge(
|
||||||
ioptions->merge_operator.get(), key, base_tag, value,
|
ioptions->merge_operator.get(), key, base_tag, value,
|
||||||
context.GetOperands(), ioptions->logger, ioptions->stats,
|
context.GetOperands(), ioptions->logger, ioptions->stats,
|
||||||
ioptions->clock, /* update_num_ops_stats */ false, results...,
|
ioptions->clock, /* update_num_ops_stats */ false,
|
||||||
/* op_failure_scope */ nullptr);
|
/* op_failure_scope */ nullptr, results...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If batch contains a value for key, store it in *value and return kFound.
|
// If batch contains a value for key, store it in *value and return kFound.
|
||||||
|
|
Loading…
Reference in New Issue