float consume() override { return DEFAULT_BOOST_SCORE; }
+ size_t estimateSize() const override { return Documents.size(); }
+
private:
llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
OS << '[';
assert(!Children.empty() && "AndIterator should have at least one child.");
// Establish invariants.
sync();
+ // When children are sorted by the estimateSize(), sync() calls are more
+ // effective. Each sync() starts with the first child and makes sure all
+ // children point to the same element. If any child is "above" the previous
+ // ones, the algorithm resets and and advances the children to the next
+ // highest element starting from the front. When child iterators in the
+ // beginning have smaller estimated size, the sync() will have less restarts
+ // and become more effective.
+ std::sort(begin(Children), end(Children),
+ [](const std::unique_ptr<Iterator> &LHS,
+ const std::unique_ptr<Iterator> &RHS) {
+ return LHS->estimateSize() < RHS->estimateSize();
+ });
}
bool reachedEnd() const override { return ReachedEnd; }
});
}
+ size_t estimateSize() const override {
+ return Children.front()->estimateSize();
+ }
+
private:
llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
OS << "(& ";
return;
// If any child goes beyond given ID (i.e. ID is not the common item),
// all children should be advanced to the next common item.
- // FIXME(kbobyrev): This is not a very optimized version; after costs
- // are introduced, cycle should break whenever ID exceeds current one
- // and cheapest children should be advanced over again.
if (Child->peek() > SyncID) {
SyncID = Child->peek();
NeedsAdvance = true;
OrIterator(std::vector<std::unique_ptr<Iterator>> AllChildren)
: Children(std::move(AllChildren)) {
assert(Children.size() > 0 && "Or Iterator must have at least one child.");
+ std::sort(begin(Children), end(Children));
}
/// Returns true if all children are exhausted.
});
}
+ size_t estimateSize() const override {
+ return std::accumulate(
+ begin(Children), end(Children), Children.front()->estimateSize(),
+ [&](size_t Current, const std::unique_ptr<Iterator> &Child) {
+ return std::max(Current, Child->estimateSize());
+ });
+ }
+
private:
llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
OS << "(| ";
float consume() override { return DEFAULT_BOOST_SCORE; }
+ size_t estimateSize() const override { return Size; }
+
private:
llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
OS << "(TRUE {" << Index << "} out of " << Size << ")";
float consume() override { return Child->consume() * Factor; }
+ size_t estimateSize() const override { return Child->estimateSize(); }
+
private:
llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
OS << "(BOOST " << Factor << ' ' << *Child << ')';
return Child->consume();
}
+ size_t estimateSize() const override {
+ return std::min(Child->estimateSize(), Limit);
+ }
+
private:
llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
OS << "(LIMIT " << Limit << '(' << ItemsLeft << ") " << *Child << ')';
createOr(create(L3), create(L4), create(L5)));
EXPECT_EQ(llvm::to_string(*Nested),
- "(& (& [{1}, 3, 5, 8, 9, END] [{1}, 5, 7, 9, END]) (| [0, {5}, "
- "END] [0, {1}, 5, END] [{END}]))");
+ "(& (| [{END}] [0, {5}, END] [0, {1}, 5, END]) (& [{1}, 5, 7, 9, "
+ "END] [{1}, 3, 5, 8, 9, END]))");
}
TEST(DexIndexIterators, Limit) {