void AdjustBuildIndex(int childi) { int targetindex = rebuild ? childi+1 : childi; if (targetindex > buildindex) { buildindex = targetindex; for (UserSet::iterator u = users.begin(); u != users.end(); ++u) { (*u)->AdjustBuildIndex(buildindex); } } }
std::string ToString(SerializeFormat format) const { std::ostringstream oss; oss << lastnotify; for (UserSet::const_iterator i = accepting.begin(); i != accepting.end(); ++i) { User* u = *i; // Encode UIDs. oss << "," << (format == FORMAT_USER ? u->nick : u->uuid); } return oss.str(); }
std::priority_queue<ProportionalFair::UserPreference> ProportionalFair::calculateUserPreferences(UserSet activeUsers, bool txStrategy) const { std::map<UserID, ChannelQualityOnOneSubChannel> sinrs; // preference for every user in a priority queue which automatically sorts std::priority_queue<UserPreference> preferences; assure(preferences.size()==0, "preferences.size() must be 0"); for ( UserSet::const_iterator iter = activeUsers.begin(); iter != activeUsers.end(); ++iter) { UserID user = *iter; assure(user.isValid(), "No valid user"); //determines the users SINRs depending on the tx/Rx mode of the strategy if (txStrategy) { sinrs[user] = colleagues.registry->estimateTxSINRAt(user); } else { sinrs[user] = colleagues.registry->estimateRxSINROf(user); } // calculate PhyModeRate for available users wns::Ratio sinr(sinrs[user].carrier / sinrs[user].interference); wns::service::phy::phymode::PhyModeInterfacePtr phyMode = colleagues.registry->getPhyModeMapper()->getBestPhyMode(sinr); assure(phyMode->isValid(),"invalid PhyMode"); // calculate userRate, which is the maximum possible data rate // for one subChannel for the best PhyMode available here float phyModeRate = phyMode->getDataRate(); // rate [b/s] of one subChannel float referenceRate; float pastDataRate = 1.0; // get the past data rate for this user: // iterate over the global past data rates map of all users and // find the past data rate for this user // there is exactly one pastDataRate value per userID int weight = colleagues.registry->getTotalNumberOfUsers(user); for (std::map<UserID, float>::const_iterator iter = pastDataRates.begin(); iter != pastDataRates.end(); ++iter) { if (iter->first/*userID*/ == user) { float dataRate = iter->second; // a RN must get a better share of the bandwidth // here: proportional to its number of users: assure(weight>0, "numberOfUsers(" <<user.getName()<<")=" << weight); dataRate /= static_cast<float>(weight); // dataRate now has the meaning of a weight. pastDataRate = dataRate; } } // for all userIDs in pastDataRates if (pastDataRate < 0.01) pastDataRate = 0.01; // preference is achievable current user rate divided by a history // factor that takes the past throughput of this user into account assure(maxRateOfSubchannel>0.0, "unknown maxRateOfSubchannel"); // goal is either rate (true) or resource (false) fairness if (rateFairness == true) { referenceRate = maxRateOfSubchannel; } else { referenceRate = phyModeRate; } // maxRateOfSubchannel is constant, with range [0..1][bit/s] float resultMaxThroughput = referenceRate / maxRateOfSubchannel; float resultPropFair = referenceRate / pastDataRate; // can be any range if (scalingBetweenMaxTPandPFair <= 0.5) { // variate the preference for each user, so that they differ a little bit (1%) // and the automatic sorting does not always give the same order // (would be a problem for identical preference weights). resultMaxThroughput *= (1 + 0.01*(*preferenceVariationDistribution)()); } float UserPref = (1.0-scalingBetweenMaxTPandPFair) * resultMaxThroughput +scalingBetweenMaxTPandPFair * resultPropFair; MESSAGE_SINGLE(NORMAL, logger, "getPreference("<<user.getName()<<"): weight=" << weight << ", pastDataRate= "<<pastDataRate<<" bit/s, UserPreference= "<<UserPref<<" (resultMaxThroughput="<<resultMaxThroughput<<",resultProportionalFair="<<resultPropFair<<")"); // calculate preferences for users and order them preferences.push(UserPreference(UserPref, user)); } return preferences; }
/** * @brief Return a vector of users but only include those that could get an SINR * that is suitable for transmission when served alone. If we can't even * transmit when the users is grouped alone, there is no point in trying to * group him with users. */ std::vector<UserID> AllPossibleGroupsGrouper::getServableUserVectorFromSet(const UserSet userSet, ModeType mode) { std::map<UserID, wns::CandI> candis; std::vector<UserID> userVector; // convert UserSet to userVector needed for calculateAllPossibleGroups for (UserSet::const_iterator iter = userSet.begin(); iter != userSet.end(); ++iter) { switch(mode) { case tx: { if (beamforming){ std::map<wns::node::Interface*, wns::Power> userNoiseIInterMap; userNoiseIInterMap.clear(); userNoiseIInterMap[iter->getNode()] = colleagues.registry->estimateTxSINRAt(*iter).interference; candis = convertMap(friends.ofdmaProvider->calculateCandIsTx(userNoiseIInterMap, x_friendliness, txPower)); } else{ // no beamforming assure(userSet.size() == 1, "We don't do beamforming, so only one-user groups are supported"); UserID user = *iter; wns::scheduler::ChannelQualityOnOneSubChannel cqi = colleagues.registry->estimateTxSINRAt(user); candis[user] = wns::CandI(cqi.carrier, cqi.interference); } } break; case rx: { if (beamforming){ std::vector<wns::node::Interface*> combination; combination.clear(); combination.push_back(iter->getNode()); candis = convertMap(friends.ofdmaProvider->calculateCandIsRx(combination, colleagues.registry->estimateRxSINROf(*iter).interference)); } else{ // no beamforming assure(userSet.size() == 1, "We don't do beamforming, so only one-user groups are supported"); UserID user = *iter; wns::scheduler::ChannelQualityOnOneSubChannel cqi = colleagues.registry->estimateRxSINROf(user); candis[user] = wns::CandI(cqi.carrier, cqi.interference); } } break; default: assure(0, "Unknown mode"); } wns::Ratio sinr(candis[*iter].C / candis[*iter].I); //if (colleagues.registry->getPhyModeForSIR(candis[*iter].C / candis[*iter].I).second > 0.0001) if (colleagues.phyModeMapper->sinrIsAboveLimit(sinr)) userVector.push_back(*iter); else { MESSAGE_BEGIN(VERBOSE, logger, m, colleagues.registry->getNameForUser(colleagues.registry->getMyUserID())); m << "removing user" << colleagues.registry->getNameForUser(*iter) << " because SINR is not sufficient even for serving the user alone"; MESSAGE_END(); } } return userVector; }