vector_iterator.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  2. #pragma once
  3. #include <algorithm>
  4. #include <string>
  5. #include <vector>
  6. #include "db/dbformat.h"
  7. #include "rocksdb/comparator.h"
  8. #include "rocksdb/iterator.h"
  9. #include "rocksdb/slice.h"
  10. #include "table/internal_iterator.h"
  11. namespace ROCKSDB_NAMESPACE {
  12. // Iterator over a vector of keys/values
  13. class VectorIterator : public InternalIterator {
  14. public:
  15. VectorIterator(std::vector<std::string> keys, std::vector<std::string> values,
  16. const CompareInterface* icmp = nullptr)
  17. : keys_(std::move(keys)),
  18. values_(std::move(values)),
  19. current_(keys_.size()),
  20. indexed_cmp_(icmp, &keys_) {
  21. assert(keys_.size() == values_.size());
  22. indices_.reserve(keys_.size());
  23. for (size_t i = 0; i < keys_.size(); i++) {
  24. indices_.push_back(i);
  25. }
  26. if (icmp != nullptr) {
  27. std::sort(indices_.begin(), indices_.end(), indexed_cmp_);
  28. }
  29. }
  30. bool Valid() const override {
  31. return !indices_.empty() && current_ < indices_.size();
  32. }
  33. void SeekToFirst() override { current_ = 0; }
  34. void SeekToLast() override { current_ = indices_.size() - 1; }
  35. void Seek(const Slice& target) override {
  36. if (indexed_cmp_.cmp != nullptr) {
  37. current_ = std::lower_bound(indices_.begin(), indices_.end(), target,
  38. indexed_cmp_) -
  39. indices_.begin();
  40. } else {
  41. current_ =
  42. std::lower_bound(keys_.begin(), keys_.end(), target.ToString()) -
  43. keys_.begin();
  44. }
  45. }
  46. void SeekForPrev(const Slice& target) override {
  47. if (indexed_cmp_.cmp != nullptr) {
  48. current_ = std::upper_bound(indices_.begin(), indices_.end(), target,
  49. indexed_cmp_) -
  50. indices_.begin();
  51. } else {
  52. current_ =
  53. std::upper_bound(keys_.begin(), keys_.end(), target.ToString()) -
  54. keys_.begin();
  55. }
  56. if (!Valid()) {
  57. SeekToLast();
  58. } else {
  59. Prev();
  60. }
  61. }
  62. void Next() override { current_++; }
  63. void Prev() override { current_--; }
  64. Slice key() const override { return Slice(keys_[indices_[current_]]); }
  65. Slice value() const override { return Slice(values_[indices_[current_]]); }
  66. Status status() const override { return Status::OK(); }
  67. bool IsKeyPinned() const override { return true; }
  68. bool IsValuePinned() const override { return true; }
  69. protected:
  70. std::vector<std::string> keys_;
  71. std::vector<std::string> values_;
  72. size_t current_;
  73. private:
  74. struct IndexedKeyComparator {
  75. IndexedKeyComparator(const CompareInterface* c,
  76. const std::vector<std::string>* ks)
  77. : cmp(c), keys(ks) {}
  78. bool operator()(size_t a, size_t b) const {
  79. return cmp->Compare((*keys)[a], (*keys)[b]) < 0;
  80. }
  81. bool operator()(size_t a, const Slice& b) const {
  82. return cmp->Compare((*keys)[a], b) < 0;
  83. }
  84. bool operator()(const Slice& a, size_t b) const {
  85. return cmp->Compare(a, (*keys)[b]) < 0;
  86. }
  87. const CompareInterface* cmp;
  88. const std::vector<std::string>* keys;
  89. };
  90. IndexedKeyComparator indexed_cmp_;
  91. std::vector<size_t> indices_;
  92. };
  93. } // namespace ROCKSDB_NAMESPACE