作者: 韩晨旭@ArcueidType(Arcueid) 10225101440 李畅@wesley 10225102463 设计文档为PLAN.md,md版本报告为README.md,pdf版本报告为Report.pdf
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
4.9 KiB

  1. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. #include "table/merger.h"
  5. #include "leveldb/comparator.h"
  6. #include "leveldb/iterator.h"
  7. #include "table/iterator_wrapper.h"
  8. namespace leveldb {
  9. namespace {
  10. class MergingIterator : public Iterator {
  11. public:
  12. MergingIterator(const Comparator* comparator, Iterator** children, int n)
  13. : comparator_(comparator),
  14. children_(new IteratorWrapper[n]),
  15. n_(n),
  16. current_(nullptr),
  17. direction_(kForward) {
  18. for (int i = 0; i < n; i++) {
  19. children_[i].Set(children[i]);
  20. }
  21. }
  22. ~MergingIterator() override { delete[] children_; }
  23. bool Valid() const override { return (current_ != nullptr); }
  24. void SeekToFirst() override {
  25. for (int i = 0; i < n_; i++) {
  26. children_[i].SeekToFirst();
  27. }
  28. FindSmallest();
  29. direction_ = kForward;
  30. }
  31. void SeekToLast() override {
  32. for (int i = 0; i < n_; i++) {
  33. children_[i].SeekToLast();
  34. }
  35. FindLargest();
  36. direction_ = kReverse;
  37. }
  38. void Seek(const Slice& target) override {
  39. for (int i = 0; i < n_; i++) {
  40. children_[i].Seek(target);
  41. }
  42. FindSmallest();
  43. direction_ = kForward;
  44. }
  45. void Next() override {
  46. assert(Valid());
  47. // Ensure that all children are positioned after key().
  48. // If we are moving in the forward direction, it is already
  49. // true for all of the non-current_ children since current_ is
  50. // the smallest child and key() == current_->key(). Otherwise,
  51. // we explicitly position the non-current_ children.
  52. if (direction_ != kForward) {
  53. for (int i = 0; i < n_; i++) {
  54. IteratorWrapper* child = &children_[i];
  55. if (child != current_) {
  56. child->Seek(key());
  57. if (child->Valid() &&
  58. comparator_->Compare(key(), child->key()) == 0) {
  59. child->Next();
  60. }
  61. }
  62. }
  63. direction_ = kForward;
  64. }
  65. current_->Next();
  66. FindSmallest();
  67. }
  68. void Prev() override {
  69. assert(Valid());
  70. // Ensure that all children are positioned before key().
  71. // If we are moving in the reverse direction, it is already
  72. // true for all of the non-current_ children since current_ is
  73. // the largest child and key() == current_->key(). Otherwise,
  74. // we explicitly position the non-current_ children.
  75. if (direction_ != kReverse) {
  76. for (int i = 0; i < n_; i++) {
  77. IteratorWrapper* child = &children_[i];
  78. if (child != current_) {
  79. child->Seek(key());
  80. if (child->Valid()) {
  81. // Child is at first entry >= key(). Step back one to be < key()
  82. child->Prev();
  83. } else {
  84. // Child has no entries >= key(). Position at last entry.
  85. child->SeekToLast();
  86. }
  87. }
  88. }
  89. direction_ = kReverse;
  90. }
  91. current_->Prev();
  92. FindLargest();
  93. }
  94. Slice key() const override {
  95. assert(Valid());
  96. return current_->key();
  97. }
  98. Slice value() const override {
  99. assert(Valid());
  100. return current_->value();
  101. }
  102. Fields fields() const override { assert(false); }
  103. Status status() const override {
  104. Status status;
  105. for (int i = 0; i < n_; i++) {
  106. status = children_[i].status();
  107. if (!status.ok()) {
  108. break;
  109. }
  110. }
  111. return status;
  112. }
  113. private:
  114. // Which direction is the iterator moving?
  115. enum Direction { kForward, kReverse };
  116. void FindSmallest();
  117. void FindLargest();
  118. // We might want to use a heap in case there are lots of children.
  119. // For now we use a simple array since we expect a very small number
  120. // of children in leveldb.
  121. const Comparator* comparator_;
  122. IteratorWrapper* children_;
  123. int n_;
  124. IteratorWrapper* current_;
  125. Direction direction_;
  126. };
  127. void MergingIterator::FindSmallest() {
  128. IteratorWrapper* smallest = nullptr;
  129. for (int i = 0; i < n_; i++) {
  130. IteratorWrapper* child = &children_[i];
  131. if (child->Valid()) {
  132. if (smallest == nullptr) {
  133. smallest = child;
  134. } else if (comparator_->Compare(child->key(), smallest->key()) < 0) {
  135. smallest = child;
  136. }
  137. }
  138. }
  139. current_ = smallest;
  140. }
  141. void MergingIterator::FindLargest() {
  142. IteratorWrapper* largest = nullptr;
  143. for (int i = n_ - 1; i >= 0; i--) {
  144. IteratorWrapper* child = &children_[i];
  145. if (child->Valid()) {
  146. if (largest == nullptr) {
  147. largest = child;
  148. } else if (comparator_->Compare(child->key(), largest->key()) > 0) {
  149. largest = child;
  150. }
  151. }
  152. }
  153. current_ = largest;
  154. }
  155. } // namespace
  156. Iterator* NewMergingIterator(const Comparator* comparator, Iterator** children,
  157. int n) {
  158. assert(n >= 0);
  159. if (n == 0) {
  160. return NewEmptyIterator();
  161. } else if (n == 1) {
  162. return children[0];
  163. } else {
  164. return new MergingIterator(comparator, children, n);
  165. }
  166. }
  167. } // namespace leveldb