INT32 _coordShardKicker::_kickShardingKey( const CoordCataInfoPtr &cataInfo, const BSONObj &updator, BSONObj &newUpdator, BOOLEAN &hasShardingKey ) { INT32 rc = SDB_OK ; UINT32 skSiteID = cataInfo->getShardingKeySiteID() ; if ( skSiteID > 0 ) { map< UINT32, BOOLEAN >::iterator it = _skSiteIDs.find( skSiteID ); if ( it != _skSiteIDs.end() ) { newUpdator = updator ; hasShardingKey = it->second ; goto done ; } } try { BSONObjBuilder bobNewUpdator( updator.objsize() ) ; BSONObj boShardingKey ; BSONObj subObj ; BOOLEAN isReplace = _isUpdateReplace( updator ) ; cataInfo->getShardingKey( boShardingKey ) ; BSONObjIterator iter( updator ) ; while ( iter.more() ) { BSONElement beTmp = iter.next() ; if ( beTmp.type() != Object ) { rc = SDB_INVALIDARG; PD_LOG( PDERROR, "updator's element must be an Object type:" "updator=%s", updator.toString().c_str() ) ; goto error ; } subObj = beTmp.embeddedObject() ; if ( isReplace && 0 == ossStrcmp( beTmp.fieldName(), CMD_ADMIN_PREFIX FIELD_OP_VALUE_KEEP ) ) { _addKeys( subObj ) ; continue ; } BSONObjBuilder subBuilder( bobNewUpdator.subobjStart( beTmp.fieldName() ) ) ; BSONObjIterator iterField( subObj ) ; while( iterField.more() ) { BSONElement beField = iterField.next() ; BSONObjIterator iterKey( boShardingKey ) ; BOOLEAN isKey = FALSE ; while( iterKey.more() ) { BSONElement beKey = iterKey.next(); const CHAR *pKey = beKey.fieldName(); const CHAR *pField = beField.fieldName(); while( *pKey == *pField && *pKey != '\0' ) { ++pKey ; ++pField ; } if ( *pKey == *pField || ( '\0' == *pKey && '.' == *pField ) || ( '.' == *pKey && '\0' == *pField ) ) { isKey = TRUE ; break ; } } if ( isKey ) { hasShardingKey = TRUE; } else { subBuilder.append( beField ) ; } } // while( iterField.more() ) subBuilder.done() ; } // while ( iter.more() ) if ( isReplace ) { UINT32 count = _addKeys( boShardingKey ) ; if ( count > 0 ) { hasShardingKey = TRUE ; } if ( !_setKeys.empty() ) { BSONObjBuilder keepBuilder( bobNewUpdator.subobjStart( CMD_ADMIN_PREFIX FIELD_OP_VALUE_KEEP ) ) ; SET_SHARDINGKEY::iterator itKey = _setKeys.begin() ; while( itKey != _setKeys.end() ) { keepBuilder.append( itKey->_pStr, (INT32)1 ) ; ++itKey ; } keepBuilder.done() ; } } // if ( isReplace ) newUpdator = bobNewUpdator.obj() ; } catch ( std::exception &e ) { rc = SDB_INVALIDARG; PD_LOG ( PDERROR,"Failed to kick sharding key from the record," "occured unexpected error: %s", e.what() ) ; goto error; } if ( skSiteID > 0 ) { _skSiteIDs.insert( pair< UINT32, BOOLEAN >( skSiteID, hasShardingKey ) ) ; } done: return rc; error: goto done; }
INT32 _coordShardKicker::_checkShardingKey( const CoordCataInfoPtr &cataInfo, const BSONObj &updator, BOOLEAN &hasInclude ) { INT32 rc = SDB_OK ; UINT32 skSiteID = cataInfo->getShardingKeySiteID() ; if ( skSiteID > 0 ) { if ( _skSiteIDs.count( skSiteID ) > 0 ) { goto done ; } _skSiteIDs.insert( pair< UINT32, BOOLEAN >( skSiteID, TRUE ) ) ; } try { BSONObjBuilder bobNewUpdator( updator.objsize() ) ; BSONObj boShardingKey ; BSONObj subObj ; BOOLEAN isReplace = _isUpdateReplace( updator ) ; cataInfo->getShardingKey( boShardingKey ) ; BSONObjIterator iter( updator ) ; while ( iter.more() ) { BSONElement beTmp = iter.next() ; if ( beTmp.type() != Object ) { rc = SDB_INVALIDARG; PD_LOG( PDERROR, "updator's element must be an Object type:" "updator=%s", updator.toString().c_str() ) ; goto error ; } subObj = beTmp.embeddedObject() ; if ( isReplace && 0 == ossStrcmp( beTmp.fieldName(), CMD_ADMIN_PREFIX FIELD_OP_VALUE_KEEP ) ) { _addKeys( subObj ) ; continue ; } BSONObjIterator iterField( subObj ) ; while( iterField.more() ) { BSONElement beField = iterField.next() ; BSONObjIterator iterKey( boShardingKey ) ; BOOLEAN isKey = FALSE ; while( iterKey.more() ) { BSONElement beKey = iterKey.next() ; const CHAR *pKey = beKey.fieldName() ; const CHAR *pField = beField.fieldName() ; while( *pKey == *pField && *pKey != '\0' ) { ++pKey ; ++pField ; } if ( *pKey == *pField || ( '\0' == *pKey && '.' == *pField ) || ( '.' == *pKey && '\0' == *pField ) ) { isKey = TRUE ; break ; } } if ( isKey ) { hasInclude = TRUE ; goto done ; } } // while( iterField.more() ) } // while ( iter.more() ) if ( isReplace && _addKeys( boShardingKey ) > 0 ) { hasInclude = TRUE ; goto done ; } } catch ( std::exception &e ) { rc = SDB_INVALIDARG; PD_LOG ( PDERROR,"Failed to check the record is include sharding-key," "occured unexpected error: %s", e.what() ) ; goto error; } done: return rc; error: goto done; }