arena_wrapped_db_iter.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #include "db/arena_wrapped_db_iter.h"
  10. #include "memory/arena.h"
  11. #include "rocksdb/env.h"
  12. #include "rocksdb/iterator.h"
  13. #include "rocksdb/options.h"
  14. #include "table/internal_iterator.h"
  15. #include "table/iterator_wrapper.h"
  16. #include "util/user_comparator_wrapper.h"
  17. namespace ROCKSDB_NAMESPACE {
  18. Status ArenaWrappedDBIter::GetProperty(std::string prop_name,
  19. std::string* prop) {
  20. if (prop_name == "rocksdb.iterator.super-version-number") {
  21. // First try to pass the value returned from inner iterator.
  22. if (!db_iter_->GetProperty(prop_name, prop).ok()) {
  23. *prop = ToString(sv_number_);
  24. }
  25. return Status::OK();
  26. }
  27. return db_iter_->GetProperty(prop_name, prop);
  28. }
  29. void ArenaWrappedDBIter::Init(Env* env, const ReadOptions& read_options,
  30. const ImmutableCFOptions& cf_options,
  31. const MutableCFOptions& mutable_cf_options,
  32. const SequenceNumber& sequence,
  33. uint64_t max_sequential_skip_in_iteration,
  34. uint64_t version_number,
  35. ReadCallback* read_callback, DBImpl* db_impl,
  36. ColumnFamilyData* cfd, bool allow_blob,
  37. bool allow_refresh) {
  38. auto mem = arena_.AllocateAligned(sizeof(DBIter));
  39. db_iter_ = new (mem) DBIter(env, read_options, cf_options, mutable_cf_options,
  40. cf_options.user_comparator, nullptr, sequence,
  41. true, max_sequential_skip_in_iteration,
  42. read_callback, db_impl, cfd, allow_blob);
  43. sv_number_ = version_number;
  44. allow_refresh_ = allow_refresh;
  45. }
  46. Status ArenaWrappedDBIter::Refresh() {
  47. if (cfd_ == nullptr || db_impl_ == nullptr || !allow_refresh_) {
  48. return Status::NotSupported("Creating renew iterator is not allowed.");
  49. }
  50. assert(db_iter_ != nullptr);
  51. // TODO(yiwu): For last_seq_same_as_publish_seq_==false, this is not the
  52. // correct behavior. Will be corrected automatically when we take a snapshot
  53. // here for the case of WritePreparedTxnDB.
  54. SequenceNumber latest_seq = db_impl_->GetLatestSequenceNumber();
  55. uint64_t cur_sv_number = cfd_->GetSuperVersionNumber();
  56. if (sv_number_ != cur_sv_number) {
  57. Env* env = db_iter_->env();
  58. db_iter_->~DBIter();
  59. arena_.~Arena();
  60. new (&arena_) Arena();
  61. SuperVersion* sv = cfd_->GetReferencedSuperVersion(db_impl_);
  62. if (read_callback_) {
  63. read_callback_->Refresh(latest_seq);
  64. }
  65. Init(env, read_options_, *(cfd_->ioptions()), sv->mutable_cf_options,
  66. latest_seq, sv->mutable_cf_options.max_sequential_skip_in_iterations,
  67. cur_sv_number, read_callback_, db_impl_, cfd_, allow_blob_,
  68. allow_refresh_);
  69. InternalIterator* internal_iter = db_impl_->NewInternalIterator(
  70. read_options_, cfd_, sv, &arena_, db_iter_->GetRangeDelAggregator(),
  71. latest_seq);
  72. SetIterUnderDBIter(internal_iter);
  73. } else {
  74. db_iter_->set_sequence(latest_seq);
  75. db_iter_->set_valid(false);
  76. }
  77. return Status::OK();
  78. }
  79. ArenaWrappedDBIter* NewArenaWrappedDbIterator(
  80. Env* env, const ReadOptions& read_options,
  81. const ImmutableCFOptions& cf_options,
  82. const MutableCFOptions& mutable_cf_options, const SequenceNumber& sequence,
  83. uint64_t max_sequential_skip_in_iterations, uint64_t version_number,
  84. ReadCallback* read_callback, DBImpl* db_impl, ColumnFamilyData* cfd,
  85. bool allow_blob, bool allow_refresh) {
  86. ArenaWrappedDBIter* iter = new ArenaWrappedDBIter();
  87. iter->Init(env, read_options, cf_options, mutable_cf_options, sequence,
  88. max_sequential_skip_in_iterations, version_number, read_callback,
  89. db_impl, cfd, allow_blob, allow_refresh);
  90. if (db_impl != nullptr && cfd != nullptr && allow_refresh) {
  91. iter->StoreRefreshInfo(read_options, db_impl, cfd, read_callback,
  92. allow_blob);
  93. }
  94. return iter;
  95. }
  96. } // namespace ROCKSDB_NAMESPACE