diff --git a/db/column_family_test.cc b/db/column_family_test.cc index 0dc9ccd09..46f3796dd 100644 --- a/db/column_family_test.cc +++ b/db/column_family_test.cc @@ -857,6 +857,7 @@ TEST(ColumnFamilyTest, NewIteratorsTest) { TEST(ColumnFamilyTest, ReadOnlyDBTest) { Open(); CreateColumnFamiliesAndReopen({"one", "two", "three", "four"}); + ASSERT_OK(Put(0, "a", "b")); ASSERT_OK(Put(1, "foo", "bla")); ASSERT_OK(Put(2, "foo", "blabla")); ASSERT_OK(Put(3, "foo", "blablabla")); @@ -870,6 +871,29 @@ TEST(ColumnFamilyTest, ReadOnlyDBTest) { ASSERT_EQ("bla", Get(1, "foo")); ASSERT_EQ("blablablabla", Get(2, "foo")); + + // test newiterators + { + std::vector iterators; + ASSERT_OK(db_->NewIterators(ReadOptions(), handles_, &iterators)); + for (auto it : iterators) { + it->SeekToFirst(); + } + ASSERT_EQ(IterStatus(iterators[0]), "a->b"); + ASSERT_EQ(IterStatus(iterators[1]), "foo->bla"); + ASSERT_EQ(IterStatus(iterators[2]), "foo->blablablabla"); + for (auto it : iterators) { + it->Next(); + } + ASSERT_EQ(IterStatus(iterators[0]), "(invalid)"); + ASSERT_EQ(IterStatus(iterators[1]), "(invalid)"); + ASSERT_EQ(IterStatus(iterators[2]), "(invalid)"); + + for (auto it : iterators) { + delete it; + } + } + Close(); // can't open dropped column family Status s = OpenReadOnly({"default", "one", "two"}); diff --git a/db/db_impl_readonly.cc b/db/db_impl_readonly.cc index b1324d072..eae8379a9 100644 --- a/db/db_impl_readonly.cc +++ b/db/db_impl_readonly.cc @@ -76,12 +76,42 @@ Iterator* DBImplReadOnly::NewIterator(const ReadOptions& options, auto cfd = cfh->cfd(); SuperVersion* super_version = cfd->GetSuperVersion()->Ref(); SequenceNumber latest_snapshot = versions_->LastSequence(); - Iterator* internal_iter = NewInternalIterator(options, cfd, super_version); - return NewDBIterator( - env_, *cfd->options(), cfd->user_comparator(), internal_iter, + auto db_iter = NewArenaWrappedDbIterator( + env_, *cfd->options(), cfd->user_comparator(), (options.snapshot != nullptr ? reinterpret_cast(options.snapshot)->number_ : latest_snapshot)); + auto internal_iter = + NewInternalIterator(options, cfd, super_version, db_iter->GetArena()); + db_iter->SetIterUnderDBIter(internal_iter); + return db_iter; +} + +Status DBImplReadOnly::NewIterators( + const ReadOptions& options, + const std::vector& column_families, + std::vector* iterators) { + if (iterators == nullptr) { + return Status::InvalidArgument("iterators not allowed to be nullptr"); + } + iterators->clear(); + iterators->reserve(column_families.size()); + SequenceNumber latest_snapshot = versions_->LastSequence(); + + for (auto cfh : column_families) { + auto cfd = reinterpret_cast(cfh)->cfd(); + auto db_iter = NewArenaWrappedDbIterator( + env_, *cfd->options(), cfd->user_comparator(), + options.snapshot != nullptr + ? reinterpret_cast(options.snapshot)->number_ + : latest_snapshot); + auto internal_iter = NewInternalIterator( + options, cfd, cfd->GetSuperVersion()->Ref(), db_iter->GetArena()); + db_iter->SetIterUnderDBIter(internal_iter); + iterators->push_back(db_iter); + } + + return Status::OK(); } Status DB::OpenForReadOnly(const Options& options, const std::string& dbname, diff --git a/db/db_impl_readonly.h b/db/db_impl_readonly.h index f4a33f425..95cdbcfae 100644 --- a/db/db_impl_readonly.h +++ b/db/db_impl_readonly.h @@ -42,11 +42,8 @@ class DBImplReadOnly : public DBImpl { virtual Status NewIterators( const ReadOptions& options, - const std::vector& column_family, - std::vector* iterators) { - // TODO - return Status::NotSupported("Not supported yet."); - } + const std::vector& column_families, + std::vector* iterators); using DBImpl::Put; virtual Status Put(const WriteOptions& options,