10225501448 李度 10225101546 陈胤遒 10215501422 高宇菲
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

191 lignes
4.8 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. virtual ~MergingIterator() { delete[] children_; }
  23. virtual bool Valid() const { return (current_ != nullptr); }
  24. virtual void SeekToFirst() {
  25. for (int i = 0; i < n_; i++) {
  26. children_[i].SeekToFirst();
  27. }
  28. FindSmallest();
  29. direction_ = kForward;
  30. }
  31. virtual void SeekToLast() {
  32. for (int i = 0; i < n_; i++) {
  33. children_[i].SeekToLast();
  34. }
  35. FindLargest();
  36. direction_ = kReverse;
  37. }
  38. virtual void Seek(const Slice& target) {
  39. for (int i = 0; i < n_; i++) {
  40. children_[i].Seek(target);
  41. }
  42. FindSmallest();
  43. direction_ = kForward;
  44. }
  45. virtual void Next() {
  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. virtual void Prev() {
  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. virtual Slice key() const {
  95. assert(Valid());
  96. return current_->key();
  97. }
  98. virtual Slice value() const {
  99. assert(Valid());
  100. return current_->value();
  101. }
  102. virtual Status status() const {
  103. Status status;
  104. for (int i = 0; i < n_; i++) {
  105. status = children_[i].status();
  106. if (!status.ok()) {
  107. break;
  108. }
  109. }
  110. return status;
  111. }
  112. private:
  113. // Which direction is the iterator moving?
  114. enum Direction { kForward, kReverse };
  115. void FindSmallest();
  116. void FindLargest();
  117. // We might want to use a heap in case there are lots of children.
  118. // For now we use a simple array since we expect a very small number
  119. // of children in leveldb.
  120. const Comparator* comparator_;
  121. IteratorWrapper* children_;
  122. int n_;
  123. IteratorWrapper* current_;
  124. Direction direction_;
  125. };
  126. void MergingIterator::FindSmallest() {
  127. IteratorWrapper* smallest = nullptr;
  128. for (int i = 0; i < n_; i++) {
  129. IteratorWrapper* child = &children_[i];
  130. if (child->Valid()) {
  131. if (smallest == nullptr) {
  132. smallest = child;
  133. } else if (comparator_->Compare(child->key(), smallest->key()) < 0) {
  134. smallest = child;
  135. }
  136. }
  137. }
  138. current_ = smallest;
  139. }
  140. void MergingIterator::FindLargest() {
  141. IteratorWrapper* largest = nullptr;
  142. for (int i = n_ - 1; i >= 0; i--) {
  143. IteratorWrapper* child = &children_[i];
  144. if (child->Valid()) {
  145. if (largest == nullptr) {
  146. largest = child;
  147. } else if (comparator_->Compare(child->key(), largest->key()) > 0) {
  148. largest = child;
  149. }
  150. }
  151. }
  152. current_ = largest;
  153. }
  154. } // namespace
  155. Iterator* NewMergingIterator(const Comparator* comparator, Iterator** children,
  156. int n) {
  157. assert(n >= 0);
  158. if (n == 0) {
  159. return NewEmptyIterator();
  160. } else if (n == 1) {
  161. return children[0];
  162. } else {
  163. return new MergingIterator(comparator, children, n);
  164. }
  165. }
  166. } // namespace leveldb