void FullMasterCM::_obsolete() { LBASSERT( !_instanceDatas.empty( )); while( _instanceDatas.size() > 1 && _commitCount > _nVersions ) { InstanceData* data = _instanceDatas.front(); if( data->commitCount >= (_commitCount - _nVersions)) break; #ifdef CO_INSTRUMENT _bytesBuffered -= data->os.getSaveBuffer().getSize(); LBINFO << _bytesBuffered << " bytes used" << std::endl; #endif #if 0 LBINFO << "Remove v" << data->os.getVersion() << " c" << data->commitCount << "@" << _commitCount << "/" << _nVersions << " from " << lunchbox::className( _object ) << " " << ObjectVersion( _object ) << std::endl; #endif _releaseInstanceData( data ); _instanceDatas.pop_front(); } _checkConsistency(); }
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; }
void FullMasterCM::addSlave( Command& command, NodeMapObjectReplyPacket& reply ) { EQ_TS_THREAD( _cmdThread ); EQASSERT( command->type == PACKETTYPE_CO_NODE ); EQASSERT( command->command == CMD_NODE_MAP_OBJECT ); NodePtr node = command.getNode(); const NodeMapObjectPacket* packet = command.get< NodeMapObjectPacket >(); const uint128_t requested = packet->requestedVersion; const uint32_t instanceID = packet->instanceID; Mutex mutex( _slaves ); EQASSERT( _version != VERSION_NONE ); _checkConsistency(); // add to subscribers ++_slavesCount[ node->getNodeID() ]; _slaves->push_back( node ); stde::usort( *_slaves ); if( requested == VERSION_NONE ) // no data to send { _sendEmptyVersion( node, instanceID, _version ); reply.version = _version; return; } const uint128_t oldest = _instanceDatas.front()->os.getVersion(); uint128_t start = (requested == VERSION_OLDEST || requested < oldest ) ? oldest : requested; uint128_t end = _version; const bool useCache = packet->masterInstanceID == _object->getInstanceID(); #ifndef NDEBUG if( requested != VERSION_OLDEST && requested < start ) EQINFO << "Mapping version " << start << " instead of requested version " << requested << std::endl; #endif reply.version = start; reply.useCache = packet->useCache && useCache; if( reply.useCache ) { if( packet->minCachedVersion <= start && packet->maxCachedVersion >= start ) { #ifdef EQ_INSTRUMENT_MULTICAST _hit += packet->maxCachedVersion + 1 - start; #endif start = packet->maxCachedVersion + 1; } else if( packet->maxCachedVersion == end ) { end = EQ_MAX( start, packet->minCachedVersion - 1 ); #ifdef EQ_INSTRUMENT_MULTICAST _hit += _version - end; #endif } // TODO else cached block in the middle, send head and tail elements } #if 0 EQLOG( 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 EQASSERT( start >= oldest ); // 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 ) { InstanceData* data = *i; EQASSERT( data ); data->os.sendMapData( node, instanceID ); #ifdef EQ_INSTRUMENT_MULTICAST ++_miss; #endif } #ifdef EQ_INSTRUMENT_MULTICAST if( _miss % 100 == 0 ) EQINFO << "Cached " << _hit << "/" << _hit + _miss << " instance data transmissions" << std::endl; #endif }