bool DataIStreamQueue::addDataPacket( const uint128_t& key, Command& command ) { EQ_TS_THREAD( _thread ); EQASSERTINFO( _pending.size() < 100, "More than 100 pending commits"); ObjectDataIStream* istream = 0; PendingStreams::iterator i = _pending.find( key ); if( i == _pending.end( )) istream = _iStreamCache.alloc(); else istream = i->second; istream->addDataPacket( command ); if( istream->isReady( )) { if( i != _pending.end( )) _pending.erase( i ); _queued.push( QueuedStream( key, istream )); EQASSERTINFO( _queued.getSize() < 100, "More than 100 queued commits" ); //EQLOG( LOG_OBJECTS ) << "Queued commit " << key << std::endl; return true; } if( i == _pending.end( )) { _pending[ key ] = istream; //EQLOG( LOG_OBJECTS ) << "New incomplete commit " << key << std::endl; return false; } //EQLOG(LOG_OBJECTS) << "Add data to incomplete commit " << key <<std::endl; return false; }
bool InstanceCache::add( const ObjectVersion& rev, const uint32_t instanceID, Command& command, const uint32_t usage ) { #ifdef EQ_INSTRUMENT_CACHE ++nWrite; #endif const NodeID nodeID = command.getNode()->getNodeID(); base::ScopedMutex<> mutex( _items ); ItemHash::const_iterator i = _items->find( rev.identifier ); if( i == _items->end( )) { Item& item = _items.data[ rev.identifier ]; item.data.masterInstanceID = instanceID; item.from = nodeID; } Item& item = _items.data[ rev.identifier ] ; if( item.data.masterInstanceID != instanceID || item.from != nodeID ) { EQASSERT( !item.access ); // same master with different instance ID?! if( item.access != 0 ) // are accessed - don't add return false; // trash data from different master mapping _releaseStreams( item ); item.data.masterInstanceID = instanceID; item.from = nodeID; item.used = usage; } else item.used = EQ_MAX( item.used, usage ); if( item.data.versions.empty( )) { item.data.versions.push_back( new ObjectDataIStream ); item.times.push_back( _clock.getTime64( )); } else if( item.data.versions.back()->getPendingVersion() == rev.version ) { if( item.data.versions.back()->isReady( )) { #ifdef EQ_INSTRUMENT_CACHE ++nWriteReady; #endif return false; // Already have stream } // else append data to stream } else { const ObjectDataIStream* previous = item.data.versions.back(); EQASSERT( previous->isReady( )); const uint128_t previousVersion = previous->getPendingVersion(); if( previousVersion > rev.version ) { #ifdef EQ_INSTRUMENT_CACHE ++nWriteOld; #endif return false; } if( ( previousVersion + 1 ) != rev.version ) // hole { EQASSERT( previousVersion < rev.version ); if( item.access != 0 ) // are accessed - don't add return false; _releaseStreams( item ); } else { EQASSERT( previous->isReady( )); } item.data.versions.push_back( new ObjectDataIStream ); item.times.push_back( _clock.getTime64( )); } EQASSERT( !item.data.versions.empty( )); ObjectDataIStream* stream = item.data.versions.back(); stream->addDataPacket( command ); if( stream->isReady( )) _size += stream->getDataSize(); _releaseItems( 1 ); _releaseItems( 0 ); #ifdef EQ_INSTRUMENT_CACHE if( _items->find( rev.identifier ) != _items->end( )) ++nWriteHit; else ++nWriteMiss; #endif return true; }
//--------------------------------------------------------------------------- // command handlers //--------------------------------------------------------------------------- bool MasterCM::_cmdSlaveDelta( Command& command ) { EQ_TS_THREAD( _cmdThread ); const ObjectSlaveDeltaPacket* packet = command.get< ObjectSlaveDeltaPacket >(); EQASSERTINFO( _pendingDeltas.size() < 100, "More than 100 unfinished slave commits!?" ); ObjectDataIStream* istream = 0; PendingStreams::iterator i = _pendingDeltas.begin(); for( ; i != _pendingDeltas.end(); ++i ) { PendingStream& pending = *i; if( pending.first == packet->commit ) { istream = pending.second; break; } } if( !istream ) { EQASSERT( i == _pendingDeltas.end( )); istream = _iStreamCache.alloc(); } istream->addDataPacket( command ); if( istream->isReady( )) { if( i != _pendingDeltas.end( )) _pendingDeltas.erase( i ); _queuedDeltas.push( istream ); _object->notifyNewVersion(); EQASSERTINFO( _queuedDeltas.getSize() < 100, "More than 100 queued slave commits!?" ); #if 0 EQLOG( LOG_OBJECTS ) << "Queued slave commit " << packet->commit << " object " << _object->getID() << " " << base::className( _object ) << std::endl; #endif } else if( i == _pendingDeltas.end( )) { _pendingDeltas.push_back( PendingStream( packet->commit, istream )); #if 0 EQLOG( LOG_OBJECTS ) << "New incomplete slave commit " << packet->commit << " object " << _object->getID() << " " << base::className( _object ) << std::endl; #endif } #if 0 else EQLOG( LOG_OBJECTS ) << "Got data for incomplete slave commit " << packet->commit << " object " << _object->getID() << " " << base::className( _object ) << std::endl; #endif return true; }