/// =-=-=-=-=-=-=- /// @brief given the property map the properties next_child and child_vector, /// select the next property in the vector to be tapped as the RR resc irods::error random_get_next_child_resource( irods::resource_child_map& _cmap, std::string& _next_child ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // if the child map is empty then just return if ( _cmap.size() > 0 ) { // =-=-=-=-=-=-=- // get the size of the map and randomly pick an index into it double rand_number = static_cast<double>( rand() ); rand_number /= static_cast<double>( RAND_MAX ); size_t target_index = ( size_t )round( ( _cmap.size() - 1 ) * rand_number ); // =-=-=-=-=-=-=- // child map is keyed by resource name so we need to count out the index // and then snag the child name from the key of the hash map size_t counter = 0; std::string next_child; irods::resource_child_map::iterator itr = _cmap.begin(); for ( ; itr != _cmap.end(); ++itr ) { if ( counter == target_index ) { next_child = itr->first; break; } else { ++counter; } } // for itr // =-=-=-=-=-=-=- // assign the next_child to the out variable _next_child = next_child; } return result; } // random_get_next_child_resource
/// =-=-=-=-=-=-=- /// @brief build a sorted list of children based on hints in the context /// string for them and their positoin in the child map // NOTE :: this assumes the order in the icat dictates the order of the RR. // the user can override that behavior with applying an index to the // child. should the resc id wrap, this should still work as it // should behave like a circular queue. irods::error build_sorted_child_vector( irods::resource_child_map& _cmap, std::vector< std::string >& _child_vector ) { // =-=-=-=-=-=-=- // vector holding all of the children size_t list_size = _cmap.size(); _child_vector.resize( list_size ); // =-=-=-=-=-=-=- // iterate over the children and look for indicies on the // childrens context strings. use those to build the initial // list. irods::resource_child_map::iterator itr; for ( itr = _cmap.begin(); itr != _cmap.end(); ++itr ) { std::string ctx = itr->second.first; irods::resource_ptr& resc = itr->second.second; if ( !ctx.empty() ) { try { // =-=-=-=-=-=-=- // cast std::string to int index size_t idx = boost::lexical_cast<int>( ctx ); if ( idx < 0 || idx >= list_size ) { irods::log( ERROR( -1, "build_sorted_child_vector - index < 0" ) ); continue; } // =-=-=-=-=-=-=- // make sure the map at this spot is already empty, could have // duplicate indicies on children if ( !_child_vector[ idx ].empty() ) { std::stringstream msg; msg << "build_sorted_child_vector - child map list is not empty "; msg << "for index " << idx << " colliding with ["; msg << _child_vector[ idx ] << "]"; irods::log( ERROR( -1, msg.str() ) ); continue; } // =-=-=-=-=-=-=- // snag child resource name std::string name; irods::error ret = resc->get_property< std::string >( irods::RESOURCE_NAME, name ); if ( !ret.ok() ) { irods::log( ERROR( -1, "build_sorted_child_vector - get property for resource name failed." ) ); continue; } // =-=-=-=-=-=-=- // finally add child to the list _child_vector[ idx ] = name; } catch ( boost::bad_lexical_cast const& ) { irods::log( ERROR( -1, "build_sorted_child_vector - lexical cast failed" ) ); } } // if ctx != empty } // for itr // =-=-=-=-=-=-=- // iterate over the children again and add in any in the holes // left from the first pass for ( itr = _cmap.begin(); itr != _cmap.end(); ++itr ) { std::string ctx = itr->second.first; irods::resource_ptr& resc = itr->second.second; // =-=-=-=-=-=-=- // skip any resource whose context is not empty // as they should have places already if ( !ctx.empty() ) { continue; } // =-=-=-=-=-=-=- // iterate over the _child_vector and find a hole to // fill in with this resource name bool filled_flg = false; size_t idx = 0; std::vector< std::string >::iterator vitr; for ( vitr = _child_vector.begin(); vitr != _child_vector.end(); ++vitr ) { if ( vitr->empty() ) { // =-=-=-=-=-=-=- // snag child resource name std::string name; irods::error ret = resc->get_property< std::string >( irods::RESOURCE_NAME, name ); if ( !ret.ok() ) { irods::log( ERROR( -1, "build_sorted_child_vector - get property for resource name failed." ) ); idx++; continue; } ( *vitr ) = name; filled_flg = true; break; } else { idx++; } } // for vitr // =-=-=-=-=-=-=- // check to ensure that the resc found its way into the list if ( false == filled_flg ) { irods::log( ERROR( -1, "build_sorted_child_vector - failed to find an entry in the resc list" ) ); } } // for itr return SUCCESS(); } // build_sorted_child_vector