Ejemplo n.º 1
0
    Status WriteOp::targetWrites( const NSTargeter& targeter,
                                  std::vector<TargetedWrite*>* targetedWrites ) {

        bool isUpdate = _itemRef.getOpType() == BatchedCommandRequest::BatchType_Update;
        bool isDelete = _itemRef.getOpType() == BatchedCommandRequest::BatchType_Delete;

        // In case of error, don't leak.
        OwnedPointerVector<ShardEndpoint> endpointsOwned;
        vector<ShardEndpoint*>& endpoints = endpointsOwned.mutableVector();

        if ( isUpdate || isDelete ) {

            // Updates/deletes targeted by query

            BSONObj queryDoc =
                isUpdate ? _itemRef.getUpdate()->getQuery() : _itemRef.getDelete()->getQuery();

            Status targetStatus = targeter.targetQuery( queryDoc, &endpoints );

            if ( targetStatus.isOK() ) {
                targetStatus =
                    isUpdate ?
                        updateTargetsOk( *this, endpoints ) : deleteTargetsOk( *this, endpoints );
            }

            if ( !targetStatus.isOK() ) return targetStatus;
        }
        else {
            dassert( _itemRef.getOpType() == BatchedCommandRequest::BatchType_Insert );

            // Inserts targeted by doc itself

            ShardEndpoint* endpoint = NULL;
            Status targetStatus = targeter.targetDoc( _itemRef.getDocument(), &endpoint );

            if ( !targetStatus.isOK() ) {
                dassert( NULL == endpoint );
                return targetStatus;
            }

            dassert( NULL != endpoint );
            endpoints.push_back( endpoint );
        }

        for ( vector<ShardEndpoint*>::iterator it = endpoints.begin(); it != endpoints.end();
            ++it ) {

            ShardEndpoint* endpoint = *it;

            _childOps.push_back( new ChildWriteOp( this ) );

            WriteOpRef ref( _itemRef.getItemIndex(), _childOps.size() - 1 );

            // For now, multiple endpoints imply no versioning
            if ( endpoints.size() == 1u ) {
                targetedWrites->push_back( new TargetedWrite( *endpoint, ref ) );
            }
            else {
                ShardEndpoint broadcastEndpoint( endpoint->shardName,
                                                 ChunkVersion::IGNORED(),
                                                 endpoint->shardHost );
                targetedWrites->push_back( new TargetedWrite( broadcastEndpoint, ref ) );
            }

            _childOps.back()->pendingWrite = targetedWrites->back();
            _childOps.back()->state = WriteOpState_Pending;
        }

        _state = WriteOpState_Pending;
        return Status::OK();
    }
Ejemplo n.º 2
0
Status WriteOp::targetWrites( const NSTargeter& targeter,
                              std::vector<TargetedWrite*>* targetedWrites ) {

    bool isUpdate = _itemRef.getOpType() == BatchedCommandRequest::BatchType_Update;
    bool isDelete = _itemRef.getOpType() == BatchedCommandRequest::BatchType_Delete;
    bool isIndexInsert = _itemRef.getRequest()->isInsertIndexRequest();

    Status targetStatus = Status::OK();
    OwnedPointerVector<ShardEndpoint> endpointsOwned;
    vector<ShardEndpoint*>& endpoints = endpointsOwned.mutableVector();

    if ( isUpdate ) {
        targetStatus = targeter.targetUpdate( *_itemRef.getUpdate(), &endpoints );
    }
    else if ( isDelete ) {
        targetStatus = targeter.targetDelete( *_itemRef.getDelete(), &endpoints );
    }
    else {
        dassert( _itemRef.getOpType() == BatchedCommandRequest::BatchType_Insert );

        ShardEndpoint* endpoint = NULL;
        // TODO: Remove the index targeting stuff once there is a command for it
        if ( !isIndexInsert ) {
            targetStatus = targeter.targetInsert( _itemRef.getDocument(), &endpoint );
        }
        else {
            // TODO: Retry index writes with stale version?
            targetStatus = targeter.targetAll( &endpoints );
        }

        if ( !targetStatus.isOK() ) {
            dassert( NULL == endpoint );
            return targetStatus;
        }

        // Store single endpoint result if we targeted a single endpoint
        if ( endpoint ) endpoints.push_back( endpoint );
    }

    // If we had an error, stop here
    if ( !targetStatus.isOK() ) return targetStatus;

    for ( vector<ShardEndpoint*>::iterator it = endpoints.begin(); it != endpoints.end();
            ++it ) {

        ShardEndpoint* endpoint = *it;

        _childOps.push_back( new ChildWriteOp( this ) );

        WriteOpRef ref( _itemRef.getItemIndex(), _childOps.size() - 1 );

        // For now, multiple endpoints imply no versioning
        if ( endpoints.size() == 1u ) {
            targetedWrites->push_back( new TargetedWrite( *endpoint, ref ) );
        }
        else {
            ShardEndpoint broadcastEndpoint( endpoint->shardName,
                                             ChunkVersion::IGNORED() );
            targetedWrites->push_back( new TargetedWrite( broadcastEndpoint, ref ) );
        }

        _childOps.back()->pendingWrite = targetedWrites->back();
        _childOps.back()->state = WriteOpState_Pending;
    }

    _state = WriteOpState_Pending;
    return Status::OK();
}