Exemplo n.º 1
0
// static
bool WorkingSetCommon::fetch(OperationContext* txn,
                             WorkingSet* workingSet,
                             WorkingSetID id,
                             unowned_ptr<SeekableRecordCursor> cursor) {
    WorkingSetMember* member = workingSet->get(id);

    // The RecordFetcher should already have been transferred out of the WSM and used.
    invariant(!member->hasFetcher());

    // We should have a RecordId but need to retrieve the obj. Get the obj now and reset all WSM
    // state appropriately.
    invariant(member->hasRecordId());

    member->obj.reset();
    auto record = cursor->seekExact(member->recordId);
    if (!record) {
        return false;
    }

    member->obj = {txn->recoveryUnit()->getSnapshotId(), record->data.releaseToBson()};

    if (member->isSuspicious) {
        // Make sure that all of the keyData is still valid for this copy of the document.
        // This ensures both that index-provided filters and sort orders still hold.
        // TODO provide a way for the query planner to opt out of this checking if it is
        // unneeded due to the structure of the plan.
        invariant(!member->keyData.empty());
        for (size_t i = 0; i < member->keyData.size(); i++) {
            BSONObjSet keys;
            // There's no need to compute the prefixes of the indexed fields that cause the index to
            // be multikey when ensuring the keyData is still valid.
            MultikeyPaths* multikeyPaths = nullptr;
            member->keyData[i].index->getKeys(member->obj.value(), &keys, multikeyPaths);
            if (!keys.count(member->keyData[i].keyData)) {
                // document would no longer be at this position in the index.
                return false;
            }
        }

        member->isSuspicious = false;
    }

    member->keyData.clear();
    workingSet->transitionToRecordIdAndObj(id);
    return true;
}
Exemplo n.º 2
0
    // static
    bool WorkingSetCommon::fetch(OperationContext* txn,
                                 WorkingSetMember* member,
                                 unowned_ptr<RecordCursor> cursor) {
        // The RecordFetcher should already have been transferred out of the WSM and used.
        invariant(!member->hasFetcher());

        // We should have a RecordId but need to retrieve the obj. Get the obj now and reset all WSM
        // state appropriately.
        invariant(member->hasLoc());

        member->obj.reset();
        auto record = cursor->seekExact(member->loc);
        if (!record) {
            return false;
        }

        member->obj = {txn->recoveryUnit()->getSnapshotId(), record->data.releaseToBson()};

        if (member->isSuspicious) {
            // Make sure that all of the keyData is still valid for this copy of the document.
            // This ensures both that index-provided filters and sort orders still hold.
            // TODO provide a way for the query planner to opt out of this checking if it is
            // unneeded due to the structure of the plan.
            invariant(!member->keyData.empty());
            for (size_t i = 0; i < member->keyData.size(); i++) {
                BSONObjSet keys;
                member->keyData[i].index->getKeys(member->obj.value(), &keys);
                if (!keys.count(member->keyData[i].keyData)) {
                    // document would no longer be at this position in the index.
                    return false;
                }
            }

            member->isSuspicious = false;
        }

        member->keyData.clear();
        member->state = WorkingSetMember::LOC_AND_UNOWNED_OBJ;
        return true;
    }