void run() {
        setup();

        insert(fromjson("{_id: 1, x: 5}"));
        insert(fromjson("{_id: 2, x: 6}"));
        insert(fromjson("{_id: 3, x: 10}"));

        std::unique_ptr<IndexScan> ixscan(
            createIndexScan(BSON("x" << 5), BSON("x" << 10), false, false));

        // Expect to get key {'': 6}.
        WorkingSetMember* member = getNext(ixscan.get());
        ASSERT_EQ(WorkingSetMember::RID_AND_IDX, member->getState());
        ASSERT_BSONOBJ_EQ(member->keyData[0].keyData, BSON("" << 6));

        // Save state and insert an indexed doc.
        ixscan->saveState();
        insert(fromjson("{_id: 4, x: 7}"));
        ixscan->restoreState();

        member = getNext(ixscan.get());
        ASSERT_EQ(WorkingSetMember::RID_AND_IDX, member->getState());
        ASSERT_BSONOBJ_EQ(member->keyData[0].keyData, BSON("" << 7));

        WorkingSetID id;
        ASSERT_EQ(PlanStage::IS_EOF, ixscan->work(&id));
        ASSERT(ixscan->isEOF());
    }
    void run() {
        setup();

        insert(fromjson("{_id: 1, x: 10}"));
        insert(fromjson("{_id: 2, x: 8}"));
        insert(fromjson("{_id: 3, x: 3}"));

        std::unique_ptr<IndexScan> ixscan(
            createIndexScan(BSON("x" << 10), BSON("x" << 5), true, true, -1 /* reverse scan */));

        // Expect to get key {'': 10} and then {'': 8}.
        WorkingSetMember* member = getNext(ixscan.get());
        ASSERT_EQ(WorkingSetMember::RID_AND_IDX, member->getState());
        ASSERT_BSONOBJ_EQ(member->keyData[0].keyData, BSON("" << 10));
        member = getNext(ixscan.get());
        ASSERT_EQ(WorkingSetMember::RID_AND_IDX, member->getState());
        ASSERT_BSONOBJ_EQ(member->keyData[0].keyData, BSON("" << 8));

        // Save state and insert an indexed doc.
        ixscan->saveState();
        insert(fromjson("{_id: 4, x: 6}"));
        insert(fromjson("{_id: 5, x: 9}"));
        ixscan->restoreState();

        // Ensure that we don't erroneously return {'': 9} or {'':3}.
        member = getNext(ixscan.get());
        ASSERT_EQ(WorkingSetMember::RID_AND_IDX, member->getState());
        ASSERT_BSONOBJ_EQ(member->keyData[0].keyData, BSON("" << 6));

        WorkingSetID id;
        ASSERT_EQ(PlanStage::IS_EOF, ixscan->work(&id));
        ASSERT(ixscan->isEOF());
    }
Exemple #3
0
        // testcount is a wrapper around runCount that
        //  - sets up a countStage
        //  - runs it
        //  - asserts count is not trivial
        //  - asserts nCounted is equal to expected_n
        //  - asserts nSkipped is correct
        void testCount(const CountRequest& request, int expected_n=kDocuments, bool indexed=false) {
            setup();
            getLocs();

            auto_ptr<WorkingSet> ws(new WorkingSet);

            StatusWithMatchExpression swme = MatchExpressionParser::parse(request.query);
            auto_ptr<MatchExpression> expression(swme.getValue());

            PlanStage* scan;
            if (indexed) {
                scan = createIndexScan(expression.get(), ws.get());
            } else {
                scan = createCollScan(expression.get(), ws.get());
            }

            CountStage countStage(&_txn, _coll, request, ws.get(), scan);

            const CountStats* stats = runCount(countStage);

            ASSERT_FALSE(stats->trivialCount);
            ASSERT_EQUALS(stats->nCounted, expected_n);
            ASSERT_EQUALS(stats->nSkipped, request.skip);
        }