Example #1
0
pair<vector<BSONObj>, vector<BSONObj>> IndexAccessMethod::setDifference(const BSONObjSet& left,
                                                                        const BSONObjSet& right) {
    // Two iterators to traverse the two sets in sorted order.
    auto leftIt = left.begin();
    auto rightIt = right.begin();
    vector<BSONObj> onlyLeft;
    vector<BSONObj> onlyRight;

    while (leftIt != left.end() && rightIt != right.end()) {
        const int cmp = leftIt->woCompare(*rightIt);
        if (cmp == 0) {
            // 'leftIt' and 'rightIt' compare equal using woCompare(), but may not be identical,
            // which should result in an index change.
            if (!leftIt->binaryEqual(*rightIt)) {
                onlyLeft.push_back(*leftIt);
                onlyRight.push_back(*rightIt);
            }
            ++leftIt;
            ++rightIt;
            continue;
        } else if (cmp > 0) {
            onlyRight.push_back(*rightIt);
            ++rightIt;
        } else {
            onlyLeft.push_back(*leftIt);
            ++leftIt;
        }
    }

    // Add the rest of 'left' to 'onlyLeft', and the rest of 'right' to 'onlyRight', if any.
    onlyLeft.insert(onlyLeft.end(), leftIt, left.end());
    onlyRight.insert(onlyRight.end(), rightIt, right.end());

    return {std::move(onlyLeft), std::move(onlyRight)};
}
Example #2
0
bool InMatchExpression::equivalent(const MatchExpression* other) const {
    if (matchType() != other->matchType()) {
        return false;
    }
    const InMatchExpression* realOther = static_cast<const InMatchExpression*>(other);
    if (path() != realOther->path()) {
        return false;
    }
    if (_hasNull != realOther->_hasNull) {
        return false;
    }
    if (_regexes.size() != realOther->_regexes.size()) {
        return false;
    }
    for (size_t i = 0; i < _regexes.size(); ++i) {
        if (!_regexes[i]->equivalent(realOther->_regexes[i].get())) {
            return false;
        }
    }
    if (!CollatorInterface::collatorsMatch(_collator, realOther->_collator)) {
        return false;
    }
    // We use an element-wise comparison to check equivalence of '_equalitySet'.  Unfortunately, we
    // can't use BSONElementSet::operator==(), as it does not use the comparator object the set is
    // initialized with (and as such, it is not collation-aware).
    if (_equalitySet.size() != realOther->_equalitySet.size()) {
        return false;
    }
    auto thisEqIt = _equalitySet.begin();
    auto otherEqIt = realOther->_equalitySet.begin();
    for (; thisEqIt != _equalitySet.end(); ++thisEqIt, ++otherEqIt) {
        const bool considerFieldName = false;
        if (thisEqIt->woCompare(*otherEqIt, considerFieldName, _collator)) {
            return false;
        }
    }
    invariant(otherEqIt == realOther->_equalitySet.end());
    return true;
}