Esempio n. 1
0
 /**
  * Check number of results returned from sort.
  */
 void checkCount(int count) {
     // No limit, should get all objects back.
     // Otherwise, result set should be smaller of limit and input data size.
     if (limit() > 0 && limit() < numObj()) {
         ASSERT_EQUALS(limit(), count);
     }
     else {
         ASSERT_EQUALS(numObj(), count);
     }
 }
Esempio n. 2
0
        IndexScanBase() {
            Client::WriteContext ctx(ns());

            for (int i = 0; i < numObj(); ++i) {
                BSONObjBuilder bob;
                bob.append("foo", i);
                bob.append("baz", i);
                bob.append("bar", numObj() - i);
                _client.insert(ns(), bob.obj());
            }

            addIndex(BSON("foo" << 1));
            addIndex(BSON("foo" << 1 << "baz" << 1));
        }
        /**
         * A template used by many tests below.
         * Fill out numObj objects, sort them in the order provided by 'direction'.
         * If extAllowed is true, sorting will use use external sorting if available.
         * If limit is not zero, we limit the output of the sort stage to 'limit' results.
         */
        void sortAndCheck(int direction) {
            WorkingSet* ws = new WorkingSet();
            MockStage* ms = new MockStage(ws);

            // Insert a mix of the various types of data.
            insertVarietyOfObjects(ms);

            SortStageParams params;
            params.pattern = BSON("foo" << direction);

            // Must fetch so we can look at the doc as a BSONObj.
            PlanExecutor runner(ws, new FetchStage(ws, new SortStage(params, ws, ms), NULL));

            // Look at pairs of objects to make sure that the sort order is pairwise (and therefore
            // totally) correct.
            BSONObj last;
            ASSERT_EQUALS(Runner::RUNNER_ADVANCED, runner.getNext(&last, NULL));

            // Count 'last'.
            int count = 1;

            BSONObj current;
            while (Runner::RUNNER_ADVANCED == runner.getNext(&current, NULL)) {
                int cmp = sgn(current.woSortOrder(last, params.pattern));
                // The next object should be equal to the previous or oriented according to the sort
                // pattern.
                ASSERT(cmp == 0 || cmp == 1);
                ++count;
                last = current;
            }

            // No limit, should get all objects back.
            ASSERT_EQUALS(numObj(), count);
        }
Esempio n. 4
0
        void makeGeoData() {
            Client::WriteContext ctx(ns());

            for (int i = 0; i < numObj(); ++i) {
                double lat = double(rand()) / RAND_MAX;
                double lng = double(rand()) / RAND_MAX;
                _client.insert(ns(), BSON("geo" << BSON_ARRAY(lng << lat)));
            }
        }
Esempio n. 5
0
        QueryStageCollectionScanBase() : _client(&_txn) {
            Client::WriteContext ctx(&_txn, ns());

            for (int i = 0; i < numObj(); ++i) {
                BSONObjBuilder bob;
                bob.append("foo", i);
                _client.insert(ns(), bob.obj());
            }
            ctx.commit();
        }
Esempio n. 6
0
        void run() {
            Client::ReadContext ctx(&_txn, ns());

            CollectionScanParams params;
            params.collection = ctx.ctx().db()->getCollection( &_txn, ns() );
            params.direction = CollectionScanParams::BACKWARD;
            params.tailable = false;

            WorkingSet* ws = new WorkingSet();
            PlanStage* ps = new CollectionScan(&_txn, params, ws, NULL);
            PlanExecutor runner(ws, ps, params.collection);

            int count = 0;
            for (BSONObj obj; PlanExecutor::ADVANCED == runner.getNext(&obj, NULL); ) {
                ++count;
                ASSERT_EQUALS(numObj() - count, obj["foo"].numberInt());
            }

            ASSERT_EQUALS(numObj(), count);
        }
Esempio n. 7
0
        void run() {
            Client::WriteContext ctx(&_txn, ns());

            Collection* coll = ctx.ctx().db()->getCollection( &_txn, ns() );

            // Get the DiskLocs that would be returned by an in-order scan.
            vector<DiskLoc> locs;
            getLocs(coll, CollectionScanParams::FORWARD, &locs);

            // Configure the scan.
            CollectionScanParams params;
            params.collection = coll;
            params.direction = CollectionScanParams::FORWARD;
            params.tailable = false;

            WorkingSet ws;
            scoped_ptr<CollectionScan> scan(new CollectionScan(&_txn, params, &ws, NULL));

            int count = 0;
            while (count < 10) {
                WorkingSetID id = WorkingSet::INVALID_ID;
                PlanStage::StageState state = scan->work(&id);
                if (PlanStage::ADVANCED == state) {
                    WorkingSetMember* member = ws.get(id);
                    ASSERT_EQUALS(coll->docFor(&_txn, locs[count])["foo"].numberInt(),
                                  member->obj["foo"].numberInt());
                    ++count;
                }
            }

            // Remove locs[count].
            scan->saveState();
            scan->invalidate(locs[count], INVALIDATION_DELETION);
            remove(coll->docFor(&_txn, locs[count]));
            scan->restoreState(&_txn);

            // Skip over locs[count].
            ++count;

            // Expect the rest.
            while (!scan->isEOF()) {
                WorkingSetID id = WorkingSet::INVALID_ID;
                PlanStage::StageState state = scan->work(&id);
                if (PlanStage::ADVANCED == state) {
                    WorkingSetMember* member = ws.get(id);
                    ASSERT_EQUALS(coll->docFor(&_txn, locs[count])["foo"].numberInt(),
                                  member->obj["foo"].numberInt());
                    ++count;
                }
            }
            ctx.commit();

            ASSERT_EQUALS(numObj(), count);
        }
Esempio n. 8
0
        void run() {
            makeGeoData();
            addIndex(BSON("geo" << "2d"));

            // 2d should also work.
            IndexScanParams params;
            params.descriptor = getIndex(BSON("geo" << "2d"));
            params.startKey = BSON("geo" << BSON("$near" << BSON_ARRAY(0 << 0)));
            params.endKey = BSONObj();
            params.endKeyInclusive = true;
            params.direction = 1;

            ASSERT_EQUALS(countResults(params), numObj());
        }
        /**
         * We feed a mix of (key, unowned, owned) data to the sort stage.
         */
        void insertVarietyOfObjects(MockStage* ms) {
            set<DiskLoc> locs;
            getLocs(&locs);

            set<DiskLoc>::iterator it = locs.begin();

            for (int i = 0; i < numObj(); ++i, ++it) {
                // Insert some owned obj data.
                WorkingSetMember member;
                member.state = WorkingSetMember::OWNED_OBJ;
                member.obj = it->obj().getOwned();
                ASSERT(member.obj.isOwned());
                ms->pushBack(member);
            }
        }
Esempio n. 10
0
        void run() {
            // Add numObj() geo points.  Make sure we get them back.
            makeGeoData();
            addIndex(BSON("geo" << "2dsphere"));

            IndexScanParams params;
            params.descriptor = getIndex(BSON("geo" << "2dsphere"));
            params.startKey = BSON("geo" << BSON("$geoNear" << BSON("$geometry"
                                   << BSON("type" << "Point"
                                        << "coordinates" << BSON_ARRAY(0 << 0)))));
            params.endKey = BSONObj();
            params.endKeyInclusive = true;
            params.direction = 1;

            ASSERT_EQUALS(countResults(params), numObj());
        }
Esempio n. 11
0
        /**
         * We feed a mix of (key, unowned, owned) data to the sort stage.
         */
        void insertVarietyOfObjects(MockStage* ms, Collection* coll) {
            set<DiskLoc> locs;
            getLocs(&locs, coll);

            set<DiskLoc>::iterator it = locs.begin();

            for (int i = 0; i < numObj(); ++i, ++it) {
                ASSERT_FALSE(it == locs.end());

                // Insert some owned obj data.
                WorkingSetMember member;
                member.loc = *it;
                member.state = WorkingSetMember::LOC_AND_UNOWNED_OBJ;
                member.obj = coll->docFor(&_txn, *it);
                ms->pushBack(member);
            }
        }
Esempio n. 12
0
        void run() {
            Client::WriteContext ctx(&_txn, ns());
            
            Database* db = ctx.ctx().db();
            Collection* coll = db->getCollection(&_txn, ns());
            if (!coll) {
                coll = db->createCollection(&_txn, ns());
            }

            WorkingSet* ws = new WorkingSet();
            MockStage* ms = new MockStage(ws);

            for (int i = 0; i < numObj(); ++i) {
                WorkingSetMember member;
                member.state = WorkingSetMember::OWNED_OBJ;

                member.obj = fromjson("{a: [1,2,3], b:[1,2,3], c:[1,2,3], d:[1,2,3,4]}");
                ms->pushBack(member);

                member.obj = fromjson("{a:1, b:1, c:1}");
                ms->pushBack(member);
            }

            SortStageParams params;
            params.collection = coll;
            params.pattern = BSON("b" << -1 << "c" << 1 << "a" << 1);
            params.limit = 0;

            // We don't get results back since we're sorting some parallel arrays.
            PlanExecutor runner(ws,
                                new FetchStage(&_txn,
                                               ws,
                                               new SortStage(&_txn, params, ws, ms), NULL, coll),
                                coll);
            PlanExecutor::ExecState runnerState = runner.getNext(NULL, NULL);
            ASSERT_EQUALS(PlanExecutor::EXEC_ERROR, runnerState);
            ctx.commit();
        }
Esempio n. 13
0
        void run() {
            Client::ReadContext ctx(&_txn, ns());

            // Configure the scan.
            CollectionScanParams params;
            params.collection = ctx.ctx().db()->getCollection( &_txn, ns() );
            params.direction = CollectionScanParams::FORWARD;
            params.tailable = false;

            // Make a scan and have the runner own it.
            WorkingSet* ws = new WorkingSet();
            PlanStage* ps = new CollectionScan(&_txn, params, ws, NULL);
            PlanExecutor runner(ws, ps, params.collection);

            int count = 0;
            for (BSONObj obj; PlanExecutor::ADVANCED == runner.getNext(&obj, NULL); ) {
                // Make sure we get the objects in the order we want
                ASSERT_EQUALS(count, obj["foo"].numberInt());
                ++count;
            }

            ASSERT_EQUALS(numObj(), count);
        }
/**
 * Test hiding of parse() and format() APIs in the Format hierarchy.
 * We test the entire hierarchy, even though this test is located in
 * the DateFormat API test.
 */
void
IntlTestDateFormatAPI::TestNameHiding(void) {

    // N.B.: This test passes if it COMPILES, since it's a test of
    // compile-time name hiding.

    UErrorCode status = U_ZERO_ERROR;
    Formattable dateObj(0, Formattable::kIsDate);
    Formattable numObj(3.1415926535897932384626433832795);
    Formattable obj;
    UnicodeString str;
    FieldPosition fpos;
    ParsePosition ppos;

    // DateFormat calling Format API
    {
        logln("DateFormat");
        DateFormat *dateFmt = DateFormat::createInstance();
        if (dateFmt) {
            dateFmt->format(dateObj, str, status);
            dateFmt->format(dateObj, str, fpos, status);
            delete dateFmt;
        } else {
            errln("FAIL: Can't create DateFormat");
        }
    }

    // SimpleDateFormat calling Format & DateFormat API
    {
        logln("SimpleDateFormat");
        status = U_ZERO_ERROR;
        SimpleDateFormat sdf(status);
        // Format API
        sdf.format(dateObj, str, status);
        sdf.format(dateObj, str, fpos, status);
        // DateFormat API
        sdf.format((UDate)0, str, fpos);
        sdf.format((UDate)0, str);
        sdf.parse(str, status);
        sdf.parse(str, ppos);
    }

    // NumberFormat calling Format API
    {
        logln("NumberFormat");
        status = U_ZERO_ERROR;
        NumberFormat *fmt = NumberFormat::createInstance(status);
        if (fmt) {
            fmt->format(numObj, str, status);
            fmt->format(numObj, str, fpos, status);
            delete fmt;
        } else {
            errln("FAIL: Can't create NumberFormat()");
        }
    }

    // DecimalFormat calling Format & NumberFormat API
    {
        logln("DecimalFormat");
        status = U_ZERO_ERROR;
        DecimalFormat fmt(status);
        if(U_SUCCESS(status)) {
          // Format API
          fmt.format(numObj, str, status);
          fmt.format(numObj, str, fpos, status);
          // NumberFormat API
          fmt.format(2.71828, str);
          fmt.format((int32_t)1234567, str);
          fmt.format(1.41421, str, fpos);
          fmt.format((int32_t)9876543, str, fpos);
          fmt.parse(str, obj, ppos);
          fmt.parse(str, obj, status);
        } else {
          errln("FAIL: Couldn't instantiate DecimalFormat, error %s. Quitting test", u_errorName(status));
        }
    }

    // ChoiceFormat calling Format & NumberFormat API
    {
        logln("ChoiceFormat");
        status = U_ZERO_ERROR;
        ChoiceFormat fmt("0#foo|1#foos|2#foos", status);
        // Format API
        fmt.format(numObj, str, status);
        fmt.format(numObj, str, fpos, status);
        // NumberFormat API
        fmt.format(2.71828, str);
        fmt.format((int32_t)1234567, str);
        fmt.format(1.41421, str, fpos);
        fmt.format((int32_t)9876543, str, fpos);
        fmt.parse(str, obj, ppos);
        fmt.parse(str, obj, status);
    }

    // MessageFormat calling Format API
    {
        logln("MessageFormat");
        status = U_ZERO_ERROR;
        MessageFormat fmt("", status);
        // Format API
        // We use dateObj, which MessageFormat should reject.
        // We're testing name hiding, not the format method.
        fmt.format(dateObj, str, status);
        fmt.format(dateObj, str, fpos, status);
    }
}
Esempio n. 15
0
        void run() {
            Client::WriteContext ctx(ns());
            fillData();

            // The data we're going to later invalidate.
            set<DiskLoc> locs;
            getLocs(&locs);

            // Build the mock stage which feeds the data.
            WorkingSet ws;
            auto_ptr<MockStage> ms(new MockStage(&ws));
            insertVarietyOfObjects(ms.get());

            SortStageParams params;
            params.pattern = BSON("foo" << 1);
            auto_ptr<SortStage> ss(new SortStage(params, &ws, ms.get()));

            const int firstRead = 10;

            // Have sort read in data from the mock stage.
            for (int i = 0; i < firstRead; ++i) {
                WorkingSetID id;
                PlanStage::StageState status = ss->work(&id);
                ASSERT_NOT_EQUALS(PlanStage::ADVANCED, status);
            }

            // We should have read in the first 'firstRead' locs.  Invalidate the first.
            ss->prepareToYield();
            set<DiskLoc>::iterator it = locs.begin();
            ss->invalidate(*it++);
            ss->recoverFromYield();

            // Read the rest of the data from the mock stage.
            while (!ms->isEOF()) {
                WorkingSetID id;
                ss->work(&id);
            }

            // Release to prevent double-deletion.
            ms.release();

            // Let's just invalidate everything now.
            ss->prepareToYield();
            while (it != locs.end()) {
                ss->invalidate(*it++);
            }
            ss->recoverFromYield();

            // The sort should still work.
            int count = 0;
            while (!ss->isEOF()) {
                WorkingSetID id;
                PlanStage::StageState status = ss->work(&id);
                if (PlanStage::ADVANCED != status) { continue; }
                WorkingSetMember* member = ws.get(id);
                ASSERT(member->hasObj());
                ASSERT(!member->hasLoc());
                ++count;
            }

            // We've invalidated everything, but only 2/3 of our data had a DiskLoc to be
            // invalidated.  We get the rest as-is.
            ASSERT_EQUALS(count, numObj());
        }
Esempio n. 16
0
        void run() {
            Client::WriteContext ctx(&_txn, ns());
            
            Database* db = ctx.ctx().db();
            Collection* coll = db->getCollection(&_txn, ns());
            if (!coll) {
                coll = db->createCollection(&_txn, ns());
            }
            fillData();

            // The data we're going to later invalidate.
            set<DiskLoc> locs;
            getLocs(&locs, coll);

            // Build the mock scan stage which feeds the data.
            WorkingSet ws;
            auto_ptr<MockStage> ms(new MockStage(&ws));
            insertVarietyOfObjects(ms.get(), coll);

            SortStageParams params;
            params.collection = coll;
            params.pattern = BSON("foo" << 1);
            params.limit = limit();
            auto_ptr<SortStage> ss(new SortStage(&_txn, params, &ws, ms.get()));

            const int firstRead = 10;

            // Have sort read in data from the mock stage.
            for (int i = 0; i < firstRead; ++i) {
                WorkingSetID id = WorkingSet::INVALID_ID;
                PlanStage::StageState status = ss->work(&id);
                ASSERT_NOT_EQUALS(PlanStage::ADVANCED, status);
            }

            // We should have read in the first 'firstRead' locs.  Invalidate the first.
            ss->saveState();
            set<DiskLoc>::iterator it = locs.begin();
            ss->invalidate(*it++, INVALIDATION_DELETION);
            ss->restoreState(&_txn);

            // Read the rest of the data from the mock stage.
            while (!ms->isEOF()) {
                WorkingSetID id = WorkingSet::INVALID_ID;
                ss->work(&id);
            }

            // Release to prevent double-deletion.
            ms.release();

            // Let's just invalidate everything now.
            ss->saveState();
            while (it != locs.end()) {
                ss->invalidate(*it++, INVALIDATION_DELETION);
            }
            ss->restoreState(&_txn);

            // Invalidation of data in the sort stage fetches it but passes it through.
            int count = 0;
            while (!ss->isEOF()) {
                WorkingSetID id = WorkingSet::INVALID_ID;
                PlanStage::StageState status = ss->work(&id);
                if (PlanStage::ADVANCED != status) { continue; }
                WorkingSetMember* member = ws.get(id);
                ASSERT(member->hasObj());
                ASSERT(!member->hasLoc());
                ++count;
            }
            ctx.commit();

            // Returns all docs.
            ASSERT_EQUALS(limit() ? limit() : numObj(), count);
        }
Esempio n. 17
0
 void run() {
     ASSERT_EQUALS(numObj(), countResults(CollectionScanParams::BACKWARD, BSONObj()));
 }
Esempio n. 18
0
 void fillData() {
     for (int i = 0; i < numObj(); ++i) {
         insert(BSON("foo" << i));
     }
 }