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(
|
||||
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
||||
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
||||
/* update_num_ops_stats */ true, &saved_value_, &pinned_value_,
|
||||
&result_type, /* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
&saved_value_, &pinned_value_, &result_type);
|
||||
return SetValueAndColumnsFromMergeResult(s, result_type);
|
||||
}
|
||||
|
||||
|
@ -1306,8 +1306,8 @@ bool DBIter::MergeWithPlainBaseValue(const Slice& value,
|
|||
const Status s = MergeHelper::TimedFullMerge(
|
||||
merge_operator_, user_key, MergeHelper::kPlainBaseValue, value,
|
||||
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
||||
/* update_num_ops_stats */ true, &saved_value_, &pinned_value_,
|
||||
&result_type, /* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
&saved_value_, &pinned_value_, &result_type);
|
||||
return SetValueAndColumnsFromMergeResult(s, result_type);
|
||||
}
|
||||
|
||||
|
@ -1319,8 +1319,8 @@ bool DBIter::MergeWithWideColumnBaseValue(const Slice& entity,
|
|||
const Status s = MergeHelper::TimedFullMerge(
|
||||
merge_operator_, user_key, MergeHelper::kWideBaseValue, entity,
|
||||
merge_context_.GetOperands(), logger_, statistics_, clock_,
|
||||
/* update_num_ops_stats */ true, &saved_value_, &pinned_value_,
|
||||
&result_type, /* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
&saved_value_, &pinned_value_, &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(),
|
||||
MergeHelper::kPlainBaseValue, v, merge_context->GetOperands(),
|
||||
s->logger, s->statistics, s->clock,
|
||||
/* update_num_ops_stats */ true, s->value, s->columns,
|
||||
/* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
s->value, s->columns);
|
||||
}
|
||||
} else if (s->value) {
|
||||
s->value->assign(v.data(), v.size());
|
||||
|
@ -1114,8 +1114,8 @@ static bool SaveValue(void* arg, const char* entry) {
|
|||
*(s->status) = MergeHelper::TimedFullMerge(
|
||||
merge_operator, s->key->user_key(), MergeHelper::kWideBaseValue,
|
||||
v, merge_context->GetOperands(), s->logger, s->statistics,
|
||||
s->clock, /* update_num_ops_stats */ true, s->value, s->columns,
|
||||
/* op_failure_scope */ nullptr);
|
||||
s->clock, /* update_num_ops_stats */ true,
|
||||
/* op_failure_scope */ nullptr, s->value, s->columns);
|
||||
}
|
||||
} else if (s->value) {
|
||||
Slice value_of_default;
|
||||
|
@ -1152,8 +1152,8 @@ static bool SaveValue(void* arg, const char* entry) {
|
|||
*(s->status) = MergeHelper::TimedFullMerge(
|
||||
merge_operator, s->key->user_key(), MergeHelper::kNoBaseValue,
|
||||
merge_context->GetOperands(), s->logger, s->statistics,
|
||||
s->clock, /* update_num_ops_stats */ true, s->value, s->columns,
|
||||
/* op_failure_scope */ nullptr);
|
||||
s->clock, /* update_num_ops_stats */ true,
|
||||
/* op_failure_scope */ nullptr, s->value, s->columns);
|
||||
} else {
|
||||
// We have found a final value (a base deletion) and have newer
|
||||
// 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(
|
||||
merge_operator, s->key->user_key(), MergeHelper::kNoBaseValue,
|
||||
merge_context->GetOperands(), s->logger, s->statistics,
|
||||
s->clock, /* update_num_ops_stats */ true, s->value, s->columns,
|
||||
/* op_failure_scope */ nullptr);
|
||||
s->clock, /* update_num_ops_stats */ true,
|
||||
/* op_failure_scope */ nullptr, s->value, s->columns);
|
||||
}
|
||||
|
||||
*(s->found_final_value) = true;
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "db/blob/prefetch_buffer_collection.h"
|
||||
#include "db/compaction/compaction_iteration_stats.h"
|
||||
#include "db/dbformat.h"
|
||||
#include "db/wide/wide_column_serialization.h"
|
||||
#include "db/wide/wide_columns_helper.h"
|
||||
#include "logging/logging.h"
|
||||
#include "monitoring/perf_context_imp.h"
|
||||
|
@ -111,9 +110,9 @@ Status MergeHelper::TimedFullMergeImpl(
|
|||
const MergeOperator* merge_operator, const Slice& key,
|
||||
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_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) {
|
||||
SystemClock* clock, bool update_num_ops_stats,
|
||||
MergeOperator::OpFailureScope* op_failure_scope, std::string* result,
|
||||
Slice* result_operand, ValueType* result_type) {
|
||||
assert(result);
|
||||
assert(result_type);
|
||||
|
||||
|
@ -173,9 +172,9 @@ Status MergeHelper::TimedFullMergeImpl(
|
|||
const MergeOperator* merge_operator, const Slice& key,
|
||||
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_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) {
|
||||
SystemClock* clock, bool update_num_ops_stats,
|
||||
MergeOperator::OpFailureScope* op_failure_scope, std::string* result_value,
|
||||
PinnableWideColumns* 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));
|
||||
}
|
||||
|
||||
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
|
||||
// POST: iter points to the first entry beyond the merge process (or the end)
|
||||
// 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,
|
||||
merge_context_.GetOperands(), logger_, stats_,
|
||||
clock_, /* update_num_ops_stats */ false,
|
||||
&merge_result, /* result_operand */ nullptr,
|
||||
&merge_result_type, &op_failure_scope);
|
||||
&op_failure_scope, &merge_result,
|
||||
/* result_operand */ nullptr, &merge_result_type);
|
||||
} else if (ikey.type == kTypeValue) {
|
||||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kPlainBaseValue,
|
||||
iter->value(), merge_context_.GetOperands(), logger_,
|
||||
stats_, clock_, /* update_num_ops_stats */ false,
|
||||
&merge_result, /* result_operand */ nullptr,
|
||||
&merge_result_type, &op_failure_scope);
|
||||
&op_failure_scope, &merge_result,
|
||||
/* result_operand */ nullptr, &merge_result_type);
|
||||
} else if (ikey.type == kTypeBlobIndex) {
|
||||
BlobIndex blob_index;
|
||||
|
||||
|
@ -559,20 +423,20 @@ Status MergeHelper::MergeUntil(InternalIterator* iter,
|
|||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kPlainBaseValue,
|
||||
blob_value, merge_context_.GetOperands(), logger_,
|
||||
stats_, clock_, /* update_num_ops_stats */ false,
|
||||
&merge_result, /* result_operand */ nullptr,
|
||||
&merge_result_type, &op_failure_scope);
|
||||
&op_failure_scope, &merge_result,
|
||||
/* result_operand */ nullptr, &merge_result_type);
|
||||
} else if (ikey.type == kTypeWideColumnEntity) {
|
||||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kWideBaseValue,
|
||||
iter->value(), merge_context_.GetOperands(), logger_,
|
||||
stats_, clock_, /* update_num_ops_stats */ false,
|
||||
&merge_result, /* result_operand */ nullptr,
|
||||
&merge_result_type, &op_failure_scope);
|
||||
&op_failure_scope, &merge_result,
|
||||
/* result_operand */ nullptr, &merge_result_type);
|
||||
} else {
|
||||
s = TimedFullMerge(user_merge_operator_, ikey.user_key, kNoBaseValue,
|
||||
merge_context_.GetOperands(), logger_, stats_,
|
||||
clock_, /* update_num_ops_stats */ false,
|
||||
&merge_result, /* result_operand */ nullptr,
|
||||
&merge_result_type, &op_failure_scope);
|
||||
&op_failure_scope, &merge_result,
|
||||
/* result_operand */ nullptr, &merge_result_type);
|
||||
}
|
||||
|
||||
// We store the result in keys_.back() and operands_.back()
|
||||
|
@ -714,9 +578,9 @@ Status MergeHelper::MergeUntil(InternalIterator* iter,
|
|||
MergeOperator::OpFailureScope op_failure_scope;
|
||||
s = TimedFullMerge(user_merge_operator_, orig_ikey.user_key, kNoBaseValue,
|
||||
merge_context_.GetOperands(), logger_, stats_, clock_,
|
||||
/* update_num_ops_stats */ false, &merge_result,
|
||||
/* result_operand */ nullptr, &merge_result_type,
|
||||
&op_failure_scope);
|
||||
/* update_num_ops_stats */ false, &op_failure_scope,
|
||||
&merge_result,
|
||||
/* result_operand */ nullptr, &merge_result_type);
|
||||
if (s.ok()) {
|
||||
// The original key encountered
|
||||
// We are certain that keys_ is not empty here (see assertions couple of
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "db/merge_context.h"
|
||||
#include "db/range_del_aggregator.h"
|
||||
#include "db/snapshot_checker.h"
|
||||
#include "db/wide/wide_column_serialization.h"
|
||||
#include "rocksdb/compaction_filter.h"
|
||||
#include "rocksdb/env.h"
|
||||
#include "rocksdb/merge_operator.h"
|
||||
|
@ -60,74 +61,73 @@ class MergeHelper {
|
|||
struct WideBaseValueTag {};
|
||||
static constexpr WideBaseValueTag kWideBaseValue{};
|
||||
|
||||
// Variants that expose the merge result directly (in serialized form for wide
|
||||
// columns) as well as its value type. Used by iterator and compaction.
|
||||
template <typename... ResultTs>
|
||||
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, Slice* result_operand,
|
||||
ValueType* result_type,
|
||||
MergeOperator::OpFailureScope* op_failure_scope);
|
||||
MergeOperator::OpFailureScope* op_failure_scope,
|
||||
ResultTs... results) {
|
||||
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(
|
||||
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::OpFailureScope* op_failure_scope, ResultTs... results) {
|
||||
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(
|
||||
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::OpFailureScope* op_failure_scope, ResultTs... results) {
|
||||
MergeOperator::MergeOperationInputV3::ExistingValue existing_value;
|
||||
|
||||
static Status 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);
|
||||
Slice entity_copy(entity);
|
||||
WideColumns existing_columns;
|
||||
|
||||
// Variants that expose the merge result translated to 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 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);
|
||||
const Status s =
|
||||
WideColumnSerialization::Deserialize(entity_copy, existing_columns);
|
||||
if (!s.ok()) {
|
||||
return s;
|
||||
}
|
||||
|
||||
static Status 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);
|
||||
existing_value = std::move(existing_columns);
|
||||
|
||||
static Status 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);
|
||||
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(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::OpFailureScope* op_failure_scope,
|
||||
ResultTs... results) {
|
||||
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
|
||||
// - a corrupted key
|
||||
|
@ -271,21 +271,27 @@ class MergeHelper {
|
|||
Statistics* statistics, SystemClock* clock, bool update_num_ops_stats,
|
||||
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(
|
||||
const MergeOperator* merge_operator, const Slice& key,
|
||||
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_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::OpFailureScope* op_failure_scope, std::string* result,
|
||||
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(
|
||||
const MergeOperator* merge_operator, const Slice& key,
|
||||
MergeOperator::MergeOperationInputV3::ExistingValue&& existing_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::OpFailureScope* op_failure_scope,
|
||||
std::string* result_value, PinnableWideColumns* result_entity);
|
||||
};
|
||||
|
||||
// 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(
|
||||
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
||||
merge_context->GetOperands(), info_log_, db_statistics_, clock_,
|
||||
/* update_num_ops_stats */ true, value ? value->GetSelf() : nullptr,
|
||||
columns, /* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
value ? value->GetSelf() : nullptr, columns);
|
||||
if (status->ok()) {
|
||||
if (LIKELY(value != nullptr)) {
|
||||
value->PinSelf();
|
||||
|
@ -2782,9 +2782,8 @@ void Version::MultiGet(const ReadOptions& read_options, MultiGetRange* range,
|
|||
*status = MergeHelper::TimedFullMerge(
|
||||
merge_operator_, user_key, MergeHelper::kNoBaseValue,
|
||||
iter->merge_context.GetOperands(), info_log_, db_statistics_, clock_,
|
||||
/* update_num_ops_stats */ true,
|
||||
iter->value ? iter->value->GetSelf() : nullptr, iter->columns,
|
||||
/* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
iter->value ? iter->value->GetSelf() : nullptr, iter->columns);
|
||||
if (LIKELY(iter->value != nullptr)) {
|
||||
iter->value->PinSelf();
|
||||
range->AddValueSize(iter->value->size());
|
||||
|
|
|
@ -2545,9 +2545,8 @@ class MemTableInserter : public WriteBatch::Handler {
|
|||
WideColumnsHelper::GetDefaultColumn(columns), {value},
|
||||
moptions->info_log, moptions->statistics,
|
||||
SystemClock::Default().get(),
|
||||
/* update_num_ops_stats */ false, &new_value,
|
||||
/* result_operand */ nullptr, &new_value_type,
|
||||
/* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ false, /* op_failure_scope */ nullptr,
|
||||
&new_value, /* result_operand */ nullptr, &new_value_type);
|
||||
} else {
|
||||
// `op_failure_scope` (an output parameter) is not provided (set to
|
||||
// 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,
|
||||
{value}, moptions->info_log, moptions->statistics,
|
||||
SystemClock::Default().get(),
|
||||
/* update_num_ops_stats */ false, &new_value,
|
||||
/* result_operand */ nullptr, &new_value_type,
|
||||
/* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ false, /* op_failure_scope */ nullptr,
|
||||
&new_value, /* result_operand */ nullptr, &new_value_type);
|
||||
}
|
||||
|
||||
if (!merge_status.ok()) {
|
||||
|
|
|
@ -232,7 +232,6 @@ bool GetContext::SaveValue(const ParsedInternalKey& parsed_key,
|
|||
return true; // to continue to the next seq
|
||||
}
|
||||
|
||||
|
||||
if (seq_ != nullptr) {
|
||||
// Set the sequence number if it is uninitialized
|
||||
if (*seq_ == kMaxSequenceNumber) {
|
||||
|
@ -496,9 +495,8 @@ void GetContext::MergeWithNoBaseValue() {
|
|||
const Status s = MergeHelper::TimedFullMerge(
|
||||
merge_operator_, user_key_, MergeHelper::kNoBaseValue,
|
||||
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
||||
/* update_num_ops_stats */ true,
|
||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_,
|
||||
/* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_);
|
||||
PostprocessMerge(s);
|
||||
}
|
||||
|
||||
|
@ -512,9 +510,8 @@ void GetContext::MergeWithPlainBaseValue(const Slice& value) {
|
|||
const Status s = MergeHelper::TimedFullMerge(
|
||||
merge_operator_, user_key_, MergeHelper::kPlainBaseValue, value,
|
||||
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
||||
/* update_num_ops_stats */ true,
|
||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_,
|
||||
/* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_);
|
||||
PostprocessMerge(s);
|
||||
}
|
||||
|
||||
|
@ -528,9 +525,8 @@ void GetContext::MergeWithWideColumnBaseValue(const Slice& entity) {
|
|||
const Status s = MergeHelper::TimedFullMerge(
|
||||
merge_operator_, user_key_, MergeHelper::kWideBaseValue, entity,
|
||||
merge_context_->GetOperands(), logger_, statistics_, clock_,
|
||||
/* update_num_ops_stats */ true,
|
||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_,
|
||||
/* op_failure_scope */ nullptr);
|
||||
/* update_num_ops_stats */ true, /* op_failure_scope */ nullptr,
|
||||
pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_);
|
||||
PostprocessMerge(s);
|
||||
}
|
||||
|
||||
|
|
|
@ -408,8 +408,8 @@ class WriteBatchWithIndexInternal {
|
|||
return MergeHelper::TimedFullMerge(
|
||||
ioptions->merge_operator.get(), key, MergeHelper::kNoBaseValue,
|
||||
context.GetOperands(), ioptions->logger, ioptions->stats,
|
||||
ioptions->clock, /* update_num_ops_stats */ false, results...,
|
||||
/* op_failure_scope */ nullptr);
|
||||
ioptions->clock, /* update_num_ops_stats */ false,
|
||||
/* op_failure_scope */ nullptr, results...);
|
||||
}
|
||||
|
||||
template <typename BaseTag, typename BaseT, typename... ResultTs>
|
||||
|
@ -432,8 +432,8 @@ class WriteBatchWithIndexInternal {
|
|||
return MergeHelper::TimedFullMerge(
|
||||
ioptions->merge_operator.get(), key, base_tag, value,
|
||||
context.GetOperands(), ioptions->logger, ioptions->stats,
|
||||
ioptions->clock, /* update_num_ops_stats */ false, results...,
|
||||
/* op_failure_scope */ nullptr);
|
||||
ioptions->clock, /* update_num_ops_stats */ false,
|
||||
/* op_failure_scope */ nullptr, results...);
|
||||
}
|
||||
|
||||
// If batch contains a value for key, store it in *value and return kFound.
|
||||
|
|
Loading…
Reference in New Issue