Dispatcher::TaskBatchPtr Dispatcher::acquireBatch( const ExecutableNode::Task &task, BatchMap ¤tBatches, TaskToBatchMap &tasksToBatches ) { MurmurHash taskHash = task.hash(); TaskToBatchMap::iterator it = tasksToBatches.find( taskHash ); if ( it != tasksToBatches.end() ) { return it->second; } MurmurHash hash = batchHash( task ); BatchMap::iterator bIt = currentBatches.find( hash ); if ( bIt != currentBatches.end() ) { TaskBatchPtr batch = bIt->second; std::vector<float> &frames = batch->frames(); const CompoundPlug *dispatcherPlug = task.node()->dispatcherPlug(); const IntPlug *batchSizePlug = dispatcherPlug->getChild<const IntPlug>( g_batchSize ); size_t batchSize = ( batchSizePlug ) ? batchSizePlug->getValue() : 1; if ( task.node()->requiresSequenceExecution() || ( frames.size() < batchSize ) ) { if ( task.hash() != MurmurHash() ) { float frame = task.context()->getFrame(); if ( std::find( frames.begin(), frames.end(), frame ) == frames.end() ) { if ( task.node()->requiresSequenceExecution() ) { frames.insert( std::lower_bound( frames.begin(), frames.end(), frame ), frame ); } else { frames.push_back( frame ); } } } if ( taskHash != MurmurHash() ) { tasksToBatches[taskHash] = batch; } return batch; } } TaskBatchPtr batch = new TaskBatch( task ); currentBatches[hash] = batch; if ( taskHash != MurmurHash() ) { tasksToBatches[taskHash] = batch; } return batch; }
IECore::MurmurHash Dispatcher::batchHash( const ExecutableNode::Task &task ) { MurmurHash result; result.append( (uint64_t)task.node() ); if ( task.hash() == MurmurHash() ) { return result; } const Context *context = task.context(); std::vector<IECore::InternedString> names; context->names( names ); for ( std::vector<IECore::InternedString>::const_iterator it = names.begin(); it != names.end(); ++it ) { // ignore the frame and the ui values if ( ( *it != g_frame ) && it->string().compare( 0, 3, "ui:" ) ) { result.append( *it ); if ( const IECore::Data *data = context->get<const IECore::Data>( *it ) ) { data->hash( result ); } } } return result; }
Dispatcher::TaskBatch::TaskBatch( const ExecutableNode::Task &task ) : m_node( task.node() ), m_context( task.context() ), m_frames(), m_requirements() { m_blindData = new CompoundData; if ( task.hash() != MurmurHash() ) { m_frames.push_back( task.context()->getFrame() ); } }
static unsigned long taskHash( const ExecutableNode::Task &t ) { const IECore::MurmurHash h = t.hash(); return tbb::tbb_hasher( h.toString() ); }