assert(s->do_merge);
if (s->value || s->columns) {
+ std::string result;
*(s->status) = MergeHelper::TimedFullMerge(
merge_operator, s->key->user_key(), &v,
- merge_context->GetOperands(), s->value, s->columns, s->logger,
- s->statistics, s->clock, /* result_operand */ nullptr,
+ merge_context->GetOperands(), &result, s->logger, s->statistics,
+ s->clock, /* result_operand */ nullptr,
/* update_num_ops_stats */ true);
+
+ if (s->status->ok()) {
+ if (s->value) {
+ *(s->value) = std::move(result);
+ } else {
+ assert(s->columns);
+ s->columns->SetPlainValue(result);
+ }
+ }
}
} else if (s->value) {
s->value->assign(v.data(), v.size());
} else if (*(s->merge_in_progress)) {
assert(s->do_merge);
- if (s->value || s->columns) {
+ if (s->value) {
+ Slice value_of_default;
+ *(s->status) = WideColumnSerialization::GetValueOfDefaultColumn(
+ v, value_of_default);
+ if (s->status->ok()) {
+ *(s->status) = MergeHelper::TimedFullMerge(
+ merge_operator, s->key->user_key(), &value_of_default,
+ merge_context->GetOperands(), s->value, s->logger,
+ s->statistics, s->clock, /* result_operand */ nullptr,
+ /* update_num_ops_stats */ true);
+ }
+ } else if (s->columns) {
+ std::string result;
*(s->status) = MergeHelper::TimedFullMergeWithEntity(
merge_operator, s->key->user_key(), v,
- merge_context->GetOperands(), s->value, s->columns, s->logger,
- s->statistics, s->clock, /* update_num_ops_stats */ true);
+ merge_context->GetOperands(), &result, s->logger, s->statistics,
+ s->clock, /* update_num_ops_stats */ true);
+
+ if (s->status->ok()) {
+ *(s->status) = s->columns->SetWideColumnValue(result);
+ }
}
} else if (s->value) {
Slice value_of_default;
case kTypeRangeDeletion: {
if (*(s->merge_in_progress)) {
if (s->value || s->columns) {
+ std::string result;
*(s->status) = MergeHelper::TimedFullMerge(
merge_operator, s->key->user_key(), nullptr,
- merge_context->GetOperands(), s->value, s->columns, s->logger,
- s->statistics, s->clock, /* result_operand */ nullptr,
+ merge_context->GetOperands(), &result, s->logger, s->statistics,
+ s->clock, /* result_operand */ nullptr,
/* update_num_ops_stats */ true);
+
+ if (s->status->ok()) {
+ if (s->value) {
+ *(s->value) = std::move(result);
+ } else {
+ assert(s->columns);
+ s->columns->SetPlainValue(result);
+ }
+ }
}
} else {
*(s->status) = Status::NotFound();
if (s->do_merge && merge_operator->ShouldMerge(
merge_context->GetOperandsDirectionBackward())) {
if (s->value || s->columns) {
+ std::string result;
*(s->status) = MergeHelper::TimedFullMerge(
merge_operator, s->key->user_key(), nullptr,
- merge_context->GetOperands(), s->value, s->columns, s->logger,
- s->statistics, s->clock, /* result_operand */ nullptr,
+ merge_context->GetOperands(), &result, s->logger, s->statistics,
+ s->clock, /* result_operand */ nullptr,
/* update_num_ops_stats */ true);
+
+ if (s->status->ok()) {
+ if (s->value) {
+ *(s->value) = std::move(result);
+ } else {
+ assert(s->columns);
+ s->columns->SetPlainValue(result);
+ }
+ }
}
*(s->found_final_value) = true;
return Status::OK();
}
-Status MergeHelper::TimedFullMerge(const MergeOperator* merge_operator,
- const Slice& key, const Slice* base_value,
- const std::vector<Slice>& operands,
- std::string* value,
- PinnableWideColumns* columns, Logger* logger,
- Statistics* statistics, SystemClock* clock,
- Slice* result_operand,
- bool update_num_ops_stats) {
- assert(value || columns);
- assert(!value || !columns);
-
- std::string result;
- const Status s =
- TimedFullMerge(merge_operator, key, base_value, operands, &result, logger,
- statistics, clock, result_operand, update_num_ops_stats);
- if (!s.ok()) {
- return s;
- }
-
- if (value) {
- *value = std::move(result);
- return Status::OK();
- }
-
- assert(columns);
- columns->SetPlainValue(result);
-
- return Status::OK();
-}
-
Status MergeHelper::TimedFullMergeWithEntity(
const MergeOperator* merge_operator, const Slice& key, Slice base_entity,
- const std::vector<Slice>& operands, std::string* value,
- PinnableWideColumns* columns, Logger* logger, Statistics* statistics,
- SystemClock* clock, bool update_num_ops_stats) {
- assert(value || columns);
- assert(!value || !columns);
-
+ const std::vector<Slice>& operands, std::string* result, Logger* logger,
+ Statistics* statistics, SystemClock* clock, bool update_num_ops_stats) {
WideColumns base_columns;
{
value_of_default = base_columns[0].value();
}
- std::string result;
+ std::string merge_result;
{
constexpr Slice* result_operand = nullptr;
const Status s = TimedFullMerge(
- merge_operator, key, &value_of_default, operands, &result, logger,
+ merge_operator, key, &value_of_default, operands, &merge_result, logger,
statistics, clock, result_operand, update_num_ops_stats);
if (!s.ok()) {
return s;
}
}
- if (value) {
- *value = std::move(result);
- return Status::OK();
- }
-
- assert(columns);
-
- std::string output;
-
if (has_default_column) {
- base_columns[0].value() = result;
+ base_columns[0].value() = merge_result;
- const Status s = WideColumnSerialization::Serialize(base_columns, output);
+ const Status s = WideColumnSerialization::Serialize(base_columns, *result);
if (!s.ok()) {
return s;
}
} else {
const Status s =
- WideColumnSerialization::Serialize(result, base_columns, output);
+ WideColumnSerialization::Serialize(merge_result, base_columns, *result);
if (!s.ok()) {
return s;
}
}
- return columns->SetWideColumnValue(output);
+ return Status::OK();
}
// PRE: iter points to the first merge type entry
Slice* result_operand,
bool update_num_ops_stats);
- static Status TimedFullMerge(const MergeOperator* merge_operator,
- const Slice& key, const Slice* base_value,
- const std::vector<Slice>& operands,
- std::string* value, PinnableWideColumns* columns,
- Logger* logger, Statistics* statistics,
- SystemClock* clock, Slice* result_operand,
- bool update_num_ops_stats);
-
static Status TimedFullMergeWithEntity(
const MergeOperator* merge_operator, const Slice& key, Slice base_entity,
- const std::vector<Slice>& operands, std::string* value,
- PinnableWideColumns* columns, Logger* logger, Statistics* statistics,
- SystemClock* clock, bool update_num_ops_stats);
+ const std::vector<Slice>& operands, std::string* result, Logger* logger,
+ Statistics* statistics, SystemClock* clock, bool update_num_ops_stats);
// During compaction, merge entries until we hit
// - a corrupted key
}
// merge_operands are in saver and we hit the beginning of the key history
// do a final merge of nullptr and operands;
- std::string* str_value = value != nullptr ? value->GetSelf() : nullptr;
- if (str_value || columns) {
+ if (value || columns) {
+ std::string result;
*status = MergeHelper::TimedFullMerge(
merge_operator_, user_key, nullptr, merge_context->GetOperands(),
- str_value, columns, info_log_, db_statistics_, clock_,
+ &result, info_log_, db_statistics_, clock_,
/* result_operand */ nullptr, /* update_num_ops_stats */ true);
if (status->ok()) {
if (LIKELY(value != nullptr)) {
+ *(value->GetSelf()) = std::move(result);
value->PinSelf();
+ } else {
+ assert(columns != nullptr);
+ columns->SetPlainValue(result);
}
}
}
assert(do_merge_);
assert(!pinnable_val_ || !columns_);
+ std::string result;
const Status s = MergeHelper::TimedFullMerge(
- merge_operator_, user_key_, value, merge_context_->GetOperands(),
- pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_, logger_,
- statistics_, clock_, /* result_operand */ nullptr,
+ merge_operator_, user_key_, value, merge_context_->GetOperands(), &result,
+ logger_, statistics_, clock_, /* result_operand */ nullptr,
/* update_num_ops_stats */ true);
if (!s.ok()) {
state_ = kCorrupt;
}
if (LIKELY(pinnable_val_ != nullptr)) {
+ *(pinnable_val_->GetSelf()) = std::move(result);
pinnable_val_->PinSelf();
+ return;
}
+
+ assert(columns_);
+ columns_->SetPlainValue(result);
}
void GetContext::MergeWithEntity(Slice entity) {
assert(do_merge_);
assert(!pinnable_val_ || !columns_);
- const Status s = MergeHelper::TimedFullMergeWithEntity(
- merge_operator_, user_key_, entity, merge_context_->GetOperands(),
- pinnable_val_ ? pinnable_val_->GetSelf() : nullptr, columns_, logger_,
- statistics_, clock_, /* update_num_ops_stats */ true);
- if (!s.ok()) {
- state_ = kCorrupt;
+ if (LIKELY(pinnable_val_ != nullptr)) {
+ Slice value_of_default;
+
+ {
+ const Status s = WideColumnSerialization::GetValueOfDefaultColumn(
+ entity, value_of_default);
+ if (!s.ok()) {
+ state_ = kCorrupt;
+ return;
+ }
+ }
+
+ {
+ const Status s = MergeHelper::TimedFullMerge(
+ merge_operator_, user_key_, &value_of_default,
+ merge_context_->GetOperands(), pinnable_val_->GetSelf(), logger_,
+ statistics_, clock_, /* result_operand */ nullptr,
+ /* update_num_ops_stats */ true);
+ if (!s.ok()) {
+ state_ = kCorrupt;
+ return;
+ }
+ }
+
+ pinnable_val_->PinSelf();
return;
}
- if (LIKELY(pinnable_val_ != nullptr)) {
- pinnable_val_->PinSelf();
+ std::string result;
+
+ {
+ const Status s = MergeHelper::TimedFullMergeWithEntity(
+ merge_operator_, user_key_, entity, merge_context_->GetOperands(),
+ &result, logger_, statistics_, clock_, /* update_num_ops_stats */ true);
+ if (!s.ok()) {
+ state_ = kCorrupt;
+ return;
+ }
+ }
+
+ {
+ assert(columns_);
+ const Status s = columns_->SetWideColumnValue(result);
+ if (!s.ok()) {
+ state_ = kCorrupt;
+ return;
+ }
}
}