Ejemplo n.º 1
0
    int KeyV1::woCompare(const KeyV1& right, const Ordering &order) const {
        const unsigned char *l = _keyData;
        const unsigned char *r = right._keyData;

        if( (*l|*r) == IsBSON ) // only can do this if cNOTUSED maintained
            return compareHybrid(right, order);

        unsigned mask = 1;
        while( 1 ) { 
            char lval = *l; 
            char rval = *r;
            {
                int x = compare(l, r); // updates l and r pointers
                if( x ) {
                    if( order.descending(mask) )
                        x = -x;
                    return x;
                }
            }

            {
                int x = ((int)(lval & cHASMORE)) - ((int)(rval & cHASMORE));
                if( x ) 
                    return x;
                if( (lval & cHASMORE) == 0 )
                    break;
            }

            mask <<= 1;
        }

        return 0;
    }
Ejemplo n.º 2
0
int BSONObj::woCompare(const BSONObj& r, const Ordering &o, bool considerFieldName) const {
    if ( isEmpty() )
        return r.isEmpty() ? 0 : -1;
    if ( r.isEmpty() )
        return 1;

    BSONObjIterator i(*this);
    BSONObjIterator j(r);
    unsigned mask = 1;
    while ( 1 ) {
        // so far, equal...

        BSONElement l = i.next();
        BSONElement r = j.next();
        if ( l.eoo() )
            return r.eoo() ? 0 : -1;
        if ( r.eoo() )
            return 1;

        int x;
        {
            x = l.woCompare( r, considerFieldName );
            if( o.descending(mask) )
                x = -x;
        }
        if ( x != 0 )
            return x;
        mask <<= 1;
    }
    return -1;
}
Ejemplo n.º 3
0
    // pre signed dates & such
    int oldCompare(const BSONObj& l,const BSONObj& r, const Ordering &o) {
        BSONObjIterator i(l);
        BSONObjIterator j(r);
        unsigned mask = 1;
        while ( 1 ) {
            // so far, equal...

            BSONElement l = i.next();
            BSONElement r = j.next();
            if ( l.eoo() )
                return r.eoo() ? 0 : -1;
            if ( r.eoo() )
                return 1;

            int x;
            {
                x = oldElemCompare(l, r);
                if( o.descending(mask) )
                    x = -x;
            }
            if ( x != 0 )
                return x;
            mask <<= 1;
        }
        return -1;
    }
Ejemplo n.º 4
0
void testPermutation(const std::vector<BSONObj>& elementsOrig,
                     const std::vector<BSONObj>& orderings,
                     bool debug) {
    // Since KeyStrings are compared using memcmp we can assume it provides a total ordering such
    // that there won't be cases where (a < b && b < c && !(a < c)). This test still needs to ensure
    // that it provides the *correct* total ordering.
    for (size_t k = 0; k < orderings.size(); k++) {
        BSONObj orderObj = orderings[k];
        Ordering ordering = Ordering::make(orderObj);
        if (debug)
            log() << "ordering: " << orderObj;

        std::vector<BSONObj> elements = elementsOrig;
        std::stable_sort(elements.begin(), elements.end(), BSONObjCmp(orderObj));

        for (size_t i = 0; i < elements.size(); i++) {
            const BSONObj& o1 = elements[i];
            if (debug)
                log() << "\to1: " << o1;
            ROUNDTRIP_ORDER(o1, ordering);

            KeyString k1(o1, ordering);

            KeyString l1(BSON("l" << o1.firstElement()), ordering);  // kLess
            KeyString g1(BSON("g" << o1.firstElement()), ordering);  // kGreater
            ASSERT_LT(l1, k1);
            ASSERT_GT(g1, k1);

            if (i + 1 < elements.size()) {
                const BSONObj& o2 = elements[i + 1];
                if (debug)
                    log() << "\t\t o2: " << o2;
                KeyString k2(o2, ordering);
                KeyString g2(BSON("g" << o2.firstElement()), ordering);
                KeyString l2(BSON("l" << o2.firstElement()), ordering);

                int bsonCmp = o1.woCompare(o2, ordering);
                invariant(bsonCmp <= 0);  // We should be sorted...

                if (bsonCmp == 0) {
                    ASSERT_EQ(k1, k2);
                } else {
                    ASSERT_LT(k1, k2);
                }

                // Test the query encodings using kLess and kGreater
                int firstElementComp = o1.firstElement().woCompare(o2.firstElement());
                if (ordering.descending(1))
                    firstElementComp = -firstElementComp;

                invariant(firstElementComp <= 0);

                if (firstElementComp == 0) {
                    // If they share a first element then l1/g1 should equal l2/g2 and l1 should be
                    // less than both and g1 should be greater than both.
                    ASSERT_EQ(l1, l2);
                    ASSERT_EQ(g1, g2);
                    ASSERT_LT(l1, k2);
                    ASSERT_GT(g1, k2);
                } else {
                    // k1 is less than k2. Less(k2) and Greater(k1) should be between them.
                    ASSERT_LT(g1, k2);
                    ASSERT_GT(l2, k1);
                }
            }
        }
    }
}