bool ObjectCM::sendSync( const MasterCMCommand& command ) { lunchbox::ScopedFastWrite mutex( _lock ); if( !_object ) { LBWARN << "Sync from detached object requested" << std::endl; return false; } const uint128_t& maxCachedVersion = command.getMaxCachedVersion(); const bool useCache = command.useCache() && command.getMasterInstanceID() == _object->getInstanceID() && maxCachedVersion == getVersion(); if( !useCache ) { ObjectInstanceDataOStream os( this ); os.enableSync( getVersion(), command ); _object->getInstanceData( os ); os.disable(); } NodePtr node = command.getNode(); node->send( CMD_NODE_SYNC_OBJECT_REPLY, useCache /*preferMulticast*/ ) << node->getNodeID() << command.getObjectID() << command.getRequestID() << true << command.useCache() << useCache; return true; }
bool ObjectCM::_initSlave( const MasterCMCommand& command, const uint128_t& replyVersion, bool replyUseCache ) { #if 0 LBLOG( LOG_OBJECTS ) << "Object id " << _object->_id << " v" << _version << ", instantiate on " << node->getNodeID() << std::endl; #endif #ifndef NDEBUG const uint128_t& version = command.getRequestedVersion(); if( version != VERSION_OLDEST && version < replyVersion ) LBINFO << "Mapping version " << replyVersion << " instead of " << version << std::endl; #endif if( replyUseCache && command.getMinCachedVersion() <= replyVersion && command.getMaxCachedVersion() >= replyVersion ) { #ifdef CO_INSTRUMENT_MULTICAST ++_hit; #endif _sendMapSuccess( command, false ); _sendMapReply( command, replyVersion, true, replyUseCache, false ); return true; } lunchbox::ScopedFastWrite mutex( _lock ); if( !_object ) { LBWARN << "Map to detached object requested" << std::endl; return false; } #ifdef CO_INSTRUMENT_MULTICAST ++_miss; #endif replyUseCache = false; _sendMapSuccess( command, true ); // send instance data ObjectInstanceDataOStream os( this ); os.enableMap( replyVersion, command.getNode(), command.getInstanceID( )); _object->getInstanceData( os ); os.disable(); if( !os.hasSentData( )) // no data, send empty command to set version _sendEmptyVersion( command, replyVersion, true /* mc */ ); _sendMapReply( command, replyVersion, true, replyUseCache, true ); return true; }
bool FullMasterCM::sendSync( const MasterCMCommand& command ) { //const uint128_t& version = command.getRequestedVersion(); const uint128_t& maxCachedVersion = command.getMaxCachedVersion(); const bool useCache = command.useCache() && command.getMasterInstanceID() == _object->getInstanceID() && maxCachedVersion == _version; if( !useCache ) { Mutex mutex( _slaves ); InstanceData* instanceData = _instanceDatas.back(); instanceData->os.sync( command ); } NodePtr node = command.getNode(); node->send( CMD_NODE_SYNC_OBJECT_REPLY, useCache /*preferMulticast*/ ) << node->getNodeID() << command.getObjectID() << command.getRequestID() << true << command.useCache() << useCache; return true; }
bool FullMasterCM::_initSlave( const MasterCMCommand& command, const uint128_t& /*replyVersion*/, bool replyUseCache ) { _checkConsistency(); const uint128_t& version = command.getRequestedVersion(); const uint128_t oldest = _instanceDatas.front()->os.getVersion(); uint128_t start = (version == VERSION_OLDEST || version < oldest ) ? oldest : version; uint128_t end = _version; #ifndef NDEBUG if( version != VERSION_OLDEST && version < start ) LBINFO << "Mapping version " << start << " instead of requested " << version << " for " << lunchbox::className( _object ) << " " << ObjectVersion( _object->getID(), _version ) << " of " << _instanceDatas.size() << "/" << _nVersions << std::endl; #endif const uint128_t& minCachedVersion = command.getMinCachedVersion(); const uint128_t& maxCachedVersion = command.getMaxCachedVersion(); const uint128_t replyVersion = start; if( replyUseCache ) { if( minCachedVersion <= start && maxCachedVersion >= start ) { #ifdef CO_INSTRUMENT_MULTICAST _hit += maxCachedVersion + 1 - start; #endif start = maxCachedVersion + 1; } else if( maxCachedVersion == end ) { end = LB_MAX( start, minCachedVersion - 1 ); #ifdef CO_INSTRUMENT_MULTICAST _hit += _version - end; #endif } // TODO else cached block in the middle, send head and tail elements } #if 0 LBLOG( LOG_OBJECTS ) << *_object << ", instantiate on " << node->getNodeID() << " with v" << ((requested == VERSION_OLDEST) ? oldest : requested) << " (" << requested << ") sending " << start << ".." << end << " have " << _version - _nVersions << ".." << _version << " " << _instanceDatas.size() << std::endl; #endif LBASSERT( start >= oldest ); bool dataSent = false; // send all instance datas from start..end InstanceDataDeque::iterator i = _instanceDatas.begin(); while( i != _instanceDatas.end() && (*i)->os.getVersion() < start ) ++i; for( ; i != _instanceDatas.end() && (*i)->os.getVersion() <= end; ++i ) { if( !dataSent ) { _sendMapSuccess( command, true ); dataSent = true; } InstanceData* data = *i; LBASSERT( data ); data->os.sendMapData( command.getRemoteNode(), command.getInstanceID( )); #ifdef CO_INSTRUMENT_MULTICAST ++_miss; #endif } if( !dataSent ) { _sendMapSuccess( command, false ); _sendMapReply( command, replyVersion, true, replyUseCache, false ); } else _sendMapReply( command, replyVersion, true, replyUseCache, true ); #ifdef CO_INSTRUMENT_MULTICAST if( _miss % 100 == 0 ) LBINFO << "Cached " << _hit << "/" << _hit + _miss << " instance data transmissions" << std::endl; #endif return true; }