Ejemplo n.º 1
0
w_rc_t ShoreTPCBEnv::load_data()
{
    // 3. Create and file up the loading workers
	long total_accounts = _scaling_factor*TPCB_ACCOUNTS_PER_BRANCH;
	long accts_per_worker = total_accounts/_loaders_to_use;

    /* This number is really flexible. Basically, it just needs to be
       high enough to give good parallelism, while remaining low
       enough not to cause too much contention. I pulled '40' out of
       thin air.
     */
    array_guard_t< guard<table_builder_t> > loaders(new guard<table_builder_t>[_loaders_to_use]);
    for(int i=0; i < _loaders_to_use; i++) {
	// the preloader thread picked up that first set of accounts...
	long start = accts_per_worker*i+TPCB_ACCOUNTS_CREATED_PER_POP_XCT;
	long count = accts_per_worker-TPCB_ACCOUNTS_CREATED_PER_POP_XCT;
	loaders[i] = new table_builder_t(this, i, _scaling_factor, start, count);
	loaders[i]->fork();
    }

    // 4. Join the loading threads
    for(int i=0; i<_loaders_to_use; i++) {
	loaders[i]->join();
    }

    return RCOK;
}
Ejemplo n.º 2
0
rc_t ShoreYCSBEnv::load_data()
{
    // Adjust the number of loaders to use, if the scaling factor is very small
    // and the total_accounts < #loaders* accounts_per_branch
    if (_scaling_factor<_loaders_to_use) {
        _loaders_to_use = _scaling_factor;
    }
    else {
        // number of prefixes must be multiple of number of loaders, otherwise load will fail
        while (static_cast<int>(_scaling_factor) % _loaders_to_use != 0) {
            _loaders_to_use--;
        }
    }

    long prefixes_per_worker = _scaling_factor/_loaders_to_use;

    array_guard_t< guard<table_builder_t> > loaders(new guard<table_builder_t>[_loaders_to_use]);
    for(int i=0; i < _loaders_to_use; i++) {
	// the preloader thread picked up that first set of accounts...
	uint64_t start = prefixes_per_worker*i;
	loaders[i] = new table_builder_t(this, i, start, prefixes_per_worker);
	loaders[i]->fork();
    }

    // 4. Join the loading threads
    for(int i=0; i<_loaders_to_use; i++) {
	loaders[i]->join();
    }

    return RCOK;
}
Ejemplo n.º 3
0
bool Storage::save()
{
	if(!isChanged_)
		return true;

	std::size_t pos = storageFilePath_.rfind('/');
	if(pos != std::string::npos) {
		std::string dir = storageFilePath_.substr(0, pos);
		if(!FileSystem::makePath(dir))
			return false;
	}

	std::ofstream file(storageFilePath_, std::ios::out | std::ios::trunc);

	if(!file.is_open())
		return false;

	Json::Value root;
	root["binaries_path"] = binariesPath_;
	root["log_socket_path"] = logSocketPath_;
	root["default_log_level"] = static_cast<int>(defaultLogLevel_);

	Json::Value prefixes(Json::arrayValue);
	for(auto it : prefixByName_) {
		if(it.first == "default")
			continue;

		Json::Value prefix;
		prefix["name"] = it.first;
		prefix["path"] = it.second;

		prefixes.append(prefix);
	}

	root["prefixes"] = prefixes;

	Json::Value loaders(Json::arrayValue);
	for(auto it : loaderByName_) {
		if(it.first == "default")
			continue;

		Json::Value loader;
		loader["name"] = it.first;
		loader["path"] = it.second;

		loaders.append(loader);
	}

	root["loaders"] = loaders;

	Json::Value links(Json::arrayValue);
	for(auto& it : linkByPath_) {
		Json::Value link;
		link["path"]   = it.first;
		link["loader"] = it.second.loader;
		link["prefix"] = it.second.prefix;
		link["target"] = it.second.target;
		link["log_level"] = static_cast<int>(it.second.level);

		links.append(link);
	}

	root["links"] = links;

	Json::StyledWriter writer;
	file << writer.write(root);

	isChanged_ = false;
	return true;
}
Ejemplo n.º 4
0
void LGen::generateClass()
{
    QString headerFileName = QDir( m_directory.c_str() ).filePath( ( m_filename + ".h" ).c_str() ) ;
    QFile loaderh( headerFileName ) ;
    if( loaderh.open( QFile::WriteOnly | QFile::Truncate ) )
    {
        QTextStream out( &loaderh ) ;
        out << "#ifndef " << m_filename.c_str() << "_H\n" ;
        out << "#define " << m_filename.c_str() << "_H\n\n" ;

        out << "#include <QCoreApplication>\n" ;
        out << "#include <QString>\n" ;
        out << "#include <QDebug>\n" ;
        out << "#include <map>\n" ;
        out << "#include <list>\n" ;
        out << "#include <QFile>\n" ;
        out << "#include <QStringList>\n" ;
        out << "#include <iostream>\n" ;
        out << "#include \"" << m_modelclass.c_str() << ".h\"\n" ;
        out << "#include <QXmlStreamReader>\n" ;

        out << "\n\n" ;
        out << "class " ;
        out << m_filename.c_str() ;
        out << "{" ;
        out << "\n\n" ;


        out << m_indent << "QString tmpClassName;\n" ;
        out << m_indent << "QString tmpClassType;\n" ;

        out << "public:\n" ;

        out << "\n" << m_indent << m_modelclass.c_str() << " load(" << m_modelclass.c_str() << "& model , std::string filename );\n" ;

        out << "\n};\n" ;
        out << "#endif" ;
    }
    else
    {
        qDebug() << "Loader failed to open" ;
    }
    loaderh.close() ;

    //source file
    QString sourceFileName = QDir( m_directory.c_str() ).filePath(( m_filename + ".cpp" ).c_str() ) ;
    QFile loaders( sourceFileName ) ;
    if( loaders.open( QFile::WriteOnly | QFile::Truncate ) )
    {
        QTextStream out( &loaders ) ;

        out << "#include \"" << m_filename.c_str() << ".h\"" ;

        out << "\n\n" << m_indent << m_modelclass.c_str() << " " << m_filename.c_str() << "::load(" << m_modelclass.c_str() << "& model , std::string filename)\n" << m_indent << "{\n" ;

        out << m_indent << m_indent << "std::map<std::pair<QString, QString>, QString> xmlTokens;\n" ;
        out << m_indent << m_indent << "typedef std::map<std::pair<QString, QString>, QString> Dict;\n" ;
        out << m_indent << m_indent << "typedef Dict::const_iterator It;\n\n" ;



        out << m_indent << m_indent << "QFile* data = new QFile(filename.c_str());\n" ;
        out << m_indent << m_indent << "if (!data->open(QIODevice::ReadOnly | QIODevice::Text)) \n" << m_indent << m_indent << "{\n" ;
        out << m_indent << m_indent << m_indent << "qDebug() << \"Not read only\";\n" ;
        out << m_indent << m_indent << "}\n\n" ;
        out << m_indent << m_indent << "QXmlStreamReader readXML(data);\n" ;
        out << m_indent << m_indent << "std::map<QString , QList< std::pair< QString , QString > > > attributes ;\n" ;
        out << m_indent << m_indent << "while(!readXML.atEnd() && !readXML.hasError()) \n" << m_indent << m_indent << "{\n" ;
        out << m_indent << m_indent << m_indent << "QXmlStreamReader::TokenType token = readXML.readNext();\n" ;
        out << m_indent << m_indent << m_indent << "if(token == QXmlStreamReader::StartDocument) \n" << m_indent << m_indent << m_indent << "{\n" ;
        out << m_indent << m_indent << m_indent << m_indent << "continue;\n" ;
        out << m_indent << m_indent << m_indent << "}\n" ;
        out << m_indent << m_indent << m_indent << "else if (readXML.isEndElement() != true) \n" << m_indent <<m_indent << m_indent << "{\n" ;
        out << m_indent << m_indent << m_indent << m_indent << "if(readXML.attributes().size()>2)\n" ;
        out << m_indent << m_indent << m_indent << m_indent << "{\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << "QList< std::pair< QString , QString > > currentAttributes;\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << "for( int i = 0 ; i < readXML.attributes().size() ; i++ )\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::pair< QString , QString > xmlAttribute ;\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "xmlAttribute = std::make_pair( readXML.attributes()[i].name().toString() , readXML.attributes()[i].value().toString() ) ;\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.append( xmlAttribute ) ;\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << "attributes[ readXML.attributes().value(\"name\").toString() ] = currentAttributes ;\n" ;
        out << m_indent << m_indent << m_indent << m_indent << m_indent << "xmlTokens[std::make_pair(readXML.attributes().value(\"type\").toString(), readXML.attributes().value(\"name\").toString())] = readXML.attributes().value(\"value\").toString();\n" ;
        out << m_indent << m_indent << m_indent << m_indent << "}\n" ;
        out << m_indent << m_indent << m_indent << "}\n" ;
        out << m_indent << m_indent << "}\n\n" ;

        for( MapType::const_iterator it = m_map.begin() ; it != m_map.end() ; ++it )
        {
            out << m_indent << m_indent << "tmpClassType = \"" << it->second << "\";\n" ;
            out << m_indent << m_indent << "tmpClassName = \"" << it->first.second << "\";\n\n" ;
            out << m_indent << m_indent << "for (It it= xmlTokens.begin(); it != xmlTokens.end(); ++it) \n" <<m_indent << m_indent << "{\n" ;

            out << m_indent << m_indent << m_indent << "if((it -> first.second).compare(tmpClassName) == 0) \n" << m_indent << m_indent << m_indent << "{\n" ;

            if( (it->second).compare( "QString" ) == 0 )
            {
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "model.set" << it->first.second ;
                out << "((QString)(it->second));\n" ;
            }
            else if( (it->second).compare( "bool" ) == 0 )
            {
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "int boolValue = ((QString)(it->second)).toInt();\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "model.set" << it->first.second ;
                out << "(static_cast<bool>(boolValue));\n" ;
            }
            else if( (it->second).compare( "double" ) == 0 )
            {
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "double doubleValue = ((QString)(it -> second)).toDouble();\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "model.set" << it->first.second ;
                out << "(doubleValue);\n" ;
            }
            else if( (it->second).compare( "int" ) == 0 )
            {
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "int intValue = ((QString)(it->second)).toInt();\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "model.set" << it->first.second ;
                out << "(intValue);\n" ;
            }
            else if( (it->second).compare( "std::map<std::pair<unsigned long,QString>,bool>" ) == 0 )
            {
                QString mapName = it->first.second + "Map" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "std::map<std::pair<unsigned long,QString>,bool> " << mapName << " ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "QList< std::pair< QString , QString > > currentAttributes = attributes[ \"" << it->first.second << "\" ];\n" ;
                //there should be at least 4 elements to load anything: type, name, itemName and itemIsChecked(). Additionally, there has to be an even number of elements
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "if( (currentAttributes.size()-2) % 3 != 0 || currentAttributes.size() < 5 )\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::cerr << \"Wrong number of attributes for \"<< it->first.second.toStdString() << \":\" << currentAttributes.size() << std::endl ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "continue ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst();\n";//the first item should be the type
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst();\n";//the 2nd item should be the name
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "int itemNb = 0 ;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "while( currentAttributes.size() > 1 )\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::pair<QString , QString> attributeName = currentAttributes[ 0 ];\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "QString name = QString(\"item\") + QString::number(itemNb) + \"Name\";\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::pair<QString , QString> attributeIsChecked = currentAttributes[ 1 ];\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "QString isChecked = QString(\"item\") + QString::number(itemNb) + \"isChecked\";\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::pair<QString , QString> attributePosition = currentAttributes[ 2 ];\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "QString position = QString(\"item\") + QString::number(itemNb) + \"Position\";\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "if( !attributeName.first.compare(name) && !attributeIsChecked.first.compare(isChecked) && !attributePosition.first.compare(position))\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::pair<unsigned long,QString> attribute ;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "attribute = std::make_pair( attributePosition.second.toULong() , attributeName.second );\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << mapName << "[ attribute ] = ( attributeIsChecked.second.toInt() != 0 ? true : false ) ;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst();\n";//the first item should be the itemXName
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst();\n";//the first item should be the itemXisChecked
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst();\n";//the first item should be the itemXPosition
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "itemNb++;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "model.set" << it->first.second << "(" << mapName << ") ;\n " ;
            }
            else if( (it->second).compare( "std::vector<std::vector<QString> >" ) == 0 )
            {
                QString tableName = it->first.second + "Table" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "std::vector<std::vector<QString> >" << tableName << " ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "QList< std::pair< QString , QString > > currentAttributes = attributes[ \"" << it->first.second << "\" ];\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "// There should be at least 4 elements to load anything: type, name, row and column.\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "if( currentAttributes.size() < 4 )\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::cerr << \"Wrong number of attributes for \"<< it->first.second.toStdString() << \":\" << currentAttributes.size() << std::endl ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "continue ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst(); // The first item should be the type\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst(); // The 2nd item should be the name\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "if( currentAttributes[0].first != \"row\" || currentAttributes[1].first != \"column\")\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::cerr << \"Wrong attribute names: it should be \\\"row\\\" and \\\"column\\\"\" << std::endl;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "continue ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "unsigned long rowSize = currentAttributes[0].second.toULong();\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "unsigned long columnSize = currentAttributes[1].second.toULong();\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst(); // The first item should be \"row\"\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst(); // The 2nd item should be \"column\"\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "// There has to be row*column additional elements\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "if( currentAttributes.size() != rowSize * columnSize )\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::cerr << \"Wrong number of attributes for \"<< it->first.second.toStdString() << \":\" << currentAttributes.size() << std::endl ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "continue ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "unsigned long rowPos = 0 ;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "unsigned long columnPos = 0 ;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "unsigned long index = 0 ;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "std::vector<QString> line;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "bool error = false;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "while( currentAttributes.size() > 0 )\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "QString attributeName = currentAttributes[ 0 ].first;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "QString name = QString(\"item_\") + QString::number(rowPos) + \"_\" + QString::number(columnPos);\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "if( attributeName.compare(name) )\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::cerr << \"Wrong name for item: \" << attributeName.toStdString() << \" - Expected: \" << name.toStdString() << std::endl ;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "error = true;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "break;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "line.push_back( currentAttributes[ 0 ].second );\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "currentAttributes.removeFirst(); //The first item should be the item_$rowPos_$columnPos\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "index++;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "rowPos=index/columnSize;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "columnPos=index%columnSize;\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "if( columnPos == 0 )\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << tableName << ".push_back(line);\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "line.clear();\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n";
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "if( !error )\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "model.set" << it->first.second << "(" << tableName << ") ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "else\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "{\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << m_indent << "std::cerr << \"Error while loading \"<< \"" << tableName << "\" << std::endl ;\n" ;
                out << m_indent << m_indent << m_indent << m_indent << m_indent << "}\n" ;
            }
            out << m_indent << m_indent << m_indent << "}\n"<<m_indent<<m_indent<<"}" ;
            out << "\n\n" ;
        }

        out << m_indent << m_indent << "return model;" ;
        out << "\n" << m_indent << "}" ;
    }
    loaders.close() ;
}
Ejemplo n.º 5
0
bool
GusdUSD_StageProxy::MultiAccessor::_Load(const UT_Array<SdfPath>& paths)
{
    if(paths.isEmpty())
        return true;

    UT_ASSERT_P(paths.size() == _size);

    typedef tbb::concurrent_unordered_set<
        SdfPath,SdfPath::Hash> ConcurrentPathSet;

    struct _ComputeUnloadedPrimsFn
    {
        _ComputeUnloadedPrimsFn(const UT_Array<SdfPath>& paths,
                                const UT_Array<exint>& indexMap,
                                const UT_Array<_PrimLoader*>& loaders,
                                UT_Array<ConcurrentPathSet*>& pathSets)
            : _paths(paths), _indexMap(indexMap),
              _loaders(loaders), _pathSets(pathSets) {}

        void    operator()(const UT_BlockedRange<size_t>& r) const
                {
                    auto* boss = UTgetInterrupt();
                    char bcnt = 0;

                    for(size_t i = r.begin(); i < r.end(); ++i) {
                        if(BOOST_UNLIKELY(!++bcnt && boss->opInterrupt()))
                            return;
                        
                        exint idx = _indexMap(i);
                        if(idx >= 0) {
                            if(auto* loader = _loaders(idx)) {
                                const SdfPath& path = _paths(i);
                                if(!path.IsEmpty() && !loader->IsLoaded(path))
                                    _pathSets(idx)->insert(path);
                            }
                        }
                    }
                }

    private:
        const UT_Array<SdfPath>&        _paths;
        const UT_Array<exint>&          _indexMap;
        const UT_Array<_PrimLoader*>&   _loaders;
        UT_Array<ConcurrentPathSet*>    _pathSets;
    };

    /* Compute sets of unloaded prims.
       This constitutes the bulk of binding time, so do this parallel.*/
    UT_Array<_PrimLoader*> loaders(_numAccessors, _numAccessors);
    UT_Array<ConcurrentPathSet*> pathSets(_numAccessors, _numAccessors);
    for(exint i = 0; i < _numAccessors; ++i) {
        if ( _accessors[i] ) {
            auto* loader = _accessors[i].GetProxy()->_primLoader;
            if(loader) {
                loaders(i) = loader;
                pathSets(i) = new ConcurrentPathSet;
            }
        }
    }

    UTparallelFor(UT_BlockedRange<size_t>(0, _size),
                  _ComputeUnloadedPrimsFn(paths, _indexMap, loaders, pathSets));

    if(UTgetInterrupt()->opInterrupt())
        return false;

    /* Load the actual prims.
       This could be done in parallel, but is probably not worth it since
       there's only work to perform the first time a prim load is requested.*/
    for(exint i = 0; i < _numAccessors; ++i) {
        if(auto* pathSet = pathSets(i)) {
            SdfPathSet pathsToLoad(pathSet->begin(), pathSet->end());
            _accessors[i]._Load(pathsToLoad);
            
            delete pathSet;
        }
    }

    return true;
}