Index: clang-tools-extra/trunk/clangd/index/dex/Iterator.h =================================================================== --- clang-tools-extra/trunk/clangd/index/dex/Iterator.h +++ clang-tools-extra/trunk/clangd/index/dex/Iterator.h @@ -129,6 +129,10 @@ std::unique_ptr createOr(std::vector> Children); +/// Returns TRUE Iterator which iterates over "virtual" PostingList containing +/// all items in range [0, Size) in an efficient manner. +std::unique_ptr createTrue(DocID Size); + /// This allows createAnd(create(...), create(...)) syntax. template std::unique_ptr createAnd(Args... args) { std::vector> Children; Index: clang-tools-extra/trunk/clangd/index/dex/Iterator.cpp =================================================================== --- clang-tools-extra/trunk/clangd/index/dex/Iterator.cpp +++ clang-tools-extra/trunk/clangd/index/dex/Iterator.cpp @@ -225,6 +225,41 @@ std::vector> Children; }; +/// TrueIterator handles PostingLists which contain all items of the index. It +/// stores size of the virtual posting list, and all operations are performed +/// in O(1). +class TrueIterator : public Iterator { +public: + TrueIterator(DocID Size) : Size(Size) {} + + bool reachedEnd() const override { return Index >= Size; } + + void advance() override { + assert(!reachedEnd() && "Can't advance iterator after it reached the end."); + ++Index; + } + + void advanceTo(DocID ID) override { + assert(!reachedEnd() && "Can't advance iterator after it reached the end."); + Index = std::min(ID, Size); + } + + DocID peek() const override { + assert(!reachedEnd() && "TrueIterator can't call peek() at the end."); + return Index; + } + +private: + llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override { + OS << "(TRUE {" << Index << "} out of " << Size << ")"; + return OS; + } + + DocID Index = 0; + /// Size of the underlying virtual PostingList. + DocID Size; +}; + } // end namespace std::vector consume(Iterator &It, size_t Limit) { @@ -249,6 +284,10 @@ return llvm::make_unique(move(Children)); } +std::unique_ptr createTrue(DocID Size) { + return llvm::make_unique(Size); +} + } // namespace dex } // namespace clangd } // namespace clang Index: clang-tools-extra/trunk/unittests/clangd/DexIndexTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clangd/DexIndexTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/DexIndexTests.cpp @@ -262,6 +262,19 @@ EXPECT_THAT(consume(*DocIterator, 0), ElementsAre()); } +TEST(DexIndexIterators, True) { + auto TrueIterator = createTrue(0U); + EXPECT_THAT(TrueIterator->reachedEnd(), true); + EXPECT_THAT(consume(*TrueIterator), ElementsAre()); + + PostingList L0 = {1, 2, 5, 7}; + TrueIterator = createTrue(7U); + EXPECT_THAT(TrueIterator->peek(), 0); + auto AndIterator = createAnd(create(L0), move(TrueIterator)); + EXPECT_THAT(AndIterator->reachedEnd(), false); + EXPECT_THAT(consume(*AndIterator), ElementsAre(1, 2, 5)); +} + testing::Matcher> trigramsAre(std::initializer_list Trigrams) { std::vector Tokens;