merge_operator.cc 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. /**
  7. * Back-end implementation details specific to the Merge Operator.
  8. */
  9. #include "rocksdb/merge_operator.h"
  10. namespace ROCKSDB_NAMESPACE {
  11. bool MergeOperator::FullMergeV2(const MergeOperationInput& merge_in,
  12. MergeOperationOutput* merge_out) const {
  13. // If FullMergeV2 is not implemented, we convert the operand_list to
  14. // std::deque<std::string> and pass it to FullMerge
  15. std::deque<std::string> operand_list_str;
  16. for (auto& op : merge_in.operand_list) {
  17. operand_list_str.emplace_back(op.data(), op.size());
  18. }
  19. return FullMerge(merge_in.key, merge_in.existing_value, operand_list_str,
  20. &merge_out->new_value, merge_in.logger);
  21. }
  22. // The default implementation of PartialMergeMulti, which invokes
  23. // PartialMerge multiple times internally and merges two operands at
  24. // a time.
  25. bool MergeOperator::PartialMergeMulti(const Slice& key,
  26. const std::deque<Slice>& operand_list,
  27. std::string* new_value,
  28. Logger* logger) const {
  29. assert(operand_list.size() >= 2);
  30. // Simply loop through the operands
  31. Slice temp_slice(operand_list[0]);
  32. for (size_t i = 1; i < operand_list.size(); ++i) {
  33. auto& operand = operand_list[i];
  34. std::string temp_value;
  35. if (!PartialMerge(key, temp_slice, operand, &temp_value, logger)) {
  36. return false;
  37. }
  38. swap(temp_value, *new_value);
  39. temp_slice = Slice(*new_value);
  40. }
  41. // The result will be in *new_value. All merges succeeded.
  42. return true;
  43. }
  44. // Given a "real" merge from the library, call the user's
  45. // associative merge function one-by-one on each of the operands.
  46. // NOTE: It is assumed that the client's merge-operator will handle any errors.
  47. bool AssociativeMergeOperator::FullMergeV2(
  48. const MergeOperationInput& merge_in,
  49. MergeOperationOutput* merge_out) const {
  50. // Simply loop through the operands
  51. Slice temp_existing;
  52. const Slice* existing_value = merge_in.existing_value;
  53. for (const auto& operand : merge_in.operand_list) {
  54. std::string temp_value;
  55. if (!Merge(merge_in.key, existing_value, operand, &temp_value,
  56. merge_in.logger)) {
  57. return false;
  58. }
  59. swap(temp_value, merge_out->new_value);
  60. temp_existing = Slice(merge_out->new_value);
  61. existing_value = &temp_existing;
  62. }
  63. // The result will be in *new_value. All merges succeeded.
  64. return true;
  65. }
  66. // Call the user defined simple merge on the operands;
  67. // NOTE: It is assumed that the client's merge-operator will handle any errors.
  68. bool AssociativeMergeOperator::PartialMerge(
  69. const Slice& key,
  70. const Slice& left_operand,
  71. const Slice& right_operand,
  72. std::string* new_value,
  73. Logger* logger) const {
  74. return Merge(key, &left_operand, right_operand, new_value, logger);
  75. }
  76. } // namespace ROCKSDB_NAMESPACE