merge_context.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. #pragma once
  7. #include <algorithm>
  8. #include <memory>
  9. #include <string>
  10. #include <vector>
  11. #include "rocksdb/slice.h"
  12. namespace ROCKSDB_NAMESPACE {
  13. const std::vector<Slice> empty_operand_list;
  14. // The merge context for merging a user key.
  15. // When doing a Get(), DB will create such a class and pass it when
  16. // issuing Get() operation to memtables and version_set. The operands
  17. // will be fetched from the context when issuing partial of full merge.
  18. class MergeContext {
  19. public:
  20. // Clear all the operands
  21. void Clear() {
  22. if (operand_list_) {
  23. operand_list_->clear();
  24. copied_operands_->clear();
  25. }
  26. }
  27. // Push a merge operand
  28. void PushOperand(const Slice& operand_slice, bool operand_pinned = false) {
  29. Initialize();
  30. SetDirectionBackward();
  31. if (operand_pinned) {
  32. operand_list_->push_back(operand_slice);
  33. } else {
  34. // We need to have our own copy of the operand since it's not pinned
  35. copied_operands_->emplace_back(
  36. new std::string(operand_slice.data(), operand_slice.size()));
  37. operand_list_->push_back(*copied_operands_->back());
  38. }
  39. }
  40. // Push back a merge operand
  41. void PushOperandBack(const Slice& operand_slice,
  42. bool operand_pinned = false) {
  43. Initialize();
  44. SetDirectionForward();
  45. if (operand_pinned) {
  46. operand_list_->push_back(operand_slice);
  47. } else {
  48. // We need to have our own copy of the operand since it's not pinned
  49. copied_operands_->emplace_back(
  50. new std::string(operand_slice.data(), operand_slice.size()));
  51. operand_list_->push_back(*copied_operands_->back());
  52. }
  53. }
  54. // return total number of operands in the list
  55. size_t GetNumOperands() const {
  56. if (!operand_list_) {
  57. return 0;
  58. }
  59. return operand_list_->size();
  60. }
  61. // Get the operand at the index.
  62. Slice GetOperand(int index) {
  63. assert(operand_list_);
  64. SetDirectionForward();
  65. return (*operand_list_)[index];
  66. }
  67. // Same as GetOperandsDirectionForward
  68. const std::vector<Slice>& GetOperands() {
  69. return GetOperandsDirectionForward();
  70. }
  71. // Return all the operands in the order as they were merged (passed to
  72. // FullMerge or FullMergeV2)
  73. const std::vector<Slice>& GetOperandsDirectionForward() {
  74. if (!operand_list_) {
  75. return empty_operand_list;
  76. }
  77. SetDirectionForward();
  78. return *operand_list_;
  79. }
  80. // Return all the operands in the reversed order relative to how they were
  81. // merged (passed to FullMerge or FullMergeV2)
  82. const std::vector<Slice>& GetOperandsDirectionBackward() {
  83. if (!operand_list_) {
  84. return empty_operand_list;
  85. }
  86. SetDirectionBackward();
  87. return *operand_list_;
  88. }
  89. private:
  90. void Initialize() {
  91. if (!operand_list_) {
  92. operand_list_.reset(new std::vector<Slice>());
  93. copied_operands_.reset(new std::vector<std::unique_ptr<std::string>>());
  94. }
  95. }
  96. void SetDirectionForward() {
  97. if (operands_reversed_ == true) {
  98. std::reverse(operand_list_->begin(), operand_list_->end());
  99. operands_reversed_ = false;
  100. }
  101. }
  102. void SetDirectionBackward() {
  103. if (operands_reversed_ == false) {
  104. std::reverse(operand_list_->begin(), operand_list_->end());
  105. operands_reversed_ = true;
  106. }
  107. }
  108. // List of operands
  109. std::unique_ptr<std::vector<Slice>> operand_list_;
  110. // Copy of operands that are not pinned.
  111. std::unique_ptr<std::vector<std::unique_ptr<std::string>>> copied_operands_;
  112. bool operands_reversed_ = true;
  113. };
  114. } // namespace ROCKSDB_NAMESPACE