OfferDataNSeq OfferCacheDataI::getFast(GetInfo& info,int limit) { info.hit = true; info.limit = limit; info.bestCount = bestOffers.size(); info.offerCount = offers.size(); OfferDataNSeq orderedOffers; { IceUtil::Mutex::Lock lock(_mutex); if( limit < 0 || (int)(bestOffers.size()+offers.size()) <= limit ) { orderedOffers = bestOffers; orderedOffers.insert( orderedOffers.end(), offers.begin(), offers.end() ); info.bestRes = bestOffers.size(); info.onlineRes = 0; info.offerRes = offers.size(); } else if( limit <= (int)bestOffers.size() ) { orderedOffers = OfferDataNSeq( bestOffers.begin(), bestOffers.begin()+limit ); info.bestRes = limit; info.onlineRes = 0; info.offerRes = 0; } else{ // bestOffers.size() < limit < bestOffers.size()+offers.size() orderedOffers = bestOffers; orderedOffers.insert( orderedOffers.end(), offers.begin(), offers.begin()+(limit-(int)bestOffers.size()) ); info.bestRes = bestOffers.size(); info.onlineRes = 0; info.offerRes = (limit-(int)bestOffers.size()); } } info.timeout = (long)((int)time(NULL)-_timeStamp); return orderedOffers; }
BackendDataPtr BackendProducer::create(int userId, const map<int,int>& weights, const MyUtil::IntSeq& applyList, const MyUtil::IntSeq& friendList, const MyUtil::IntSeq& blockList, const MyUtil::IntSeq& commBlockList, std::ostringstream& createLog, std::ostringstream& createDetail) { OfferDataNSeq offerCommonFriend = createFromCommonFriend(userId, 300, weights, applyList, friendList, blockList, commBlockList, createLog,createDetail); //MCE_INFO("[BackendProducer] create userId:" << userId << " weights size:" << weights.size() // << " offerCommonFriend size:" << offerCommonFriend.size()); map<int, OfferDataNSeq> offerSameInfoFriends = createFromSameInfoFriend(userId, 300, weights, applyList, friendList, blockList, commBlockList, createLog,createDetail); MCE_INFO("[BackendProducer] create userId:" << userId << " weights size:" << weights.size() << " offerCommonFriend size:" << offerCommonFriend.size() << " offerSameInfoFriends size : " << offerSameInfoFriends.size()); OfferDataNSeq offerIPFriend = createFromIPFriend( userId, 300, weights, applyList, friendList, blockList, commBlockList, createLog,createDetail ); BackendDataPtr res = new BackendData(); res->add(BaseTypeCommonFriend, offerCommonFriend); map<int,OfferDataNSeq>::iterator it = offerSameInfoFriends.find(BaseTypeSameInfoWorkPlace); if( it!=offerSameInfoFriends.end() ){ res->add(BaseTypeSameInfoWorkPlace,it->second); } it = offerSameInfoFriends.find(BaseTypeSameInfoUniv); if( it!=offerSameInfoFriends.end() ){ res->add(BaseTypeSameInfoUniv,it->second); } it = offerSameInfoFriends.find(BaseTypeSameInfoHighSchool); if( it!=offerSameInfoFriends.end() ){ res->add(BaseTypeSameInfoHighSchool,it->second); } it = offerSameInfoFriends.find(BaseTypeSameInfoJuniorSchool); if( it!=offerSameInfoFriends.end() ){ res->add(BaseTypeSameInfoJuniorSchool,it->second); } it = offerSameInfoFriends.find(BaseTypeSameInfoElementarySchool); if( it!=offerSameInfoFriends.end() ){ res->add(BaseTypeSameInfoElementarySchool,it->second); } res->add(BaseTypeIPSame,offerIPFriend); return res; }
OfferDataNSeq BackendProducer::createFromIPFriend( int userId, int ipFriendLimit, const map<int,int>& weights, const IntSeq& applyList, const IntSeq& friendList, const IntSeq& blockList, const IntSeq& commBlockList, ostringstream& createLog, ostringstream& createDetail ){ struct timeval tvStart, tvIP; gettimeofday( &tvStart, NULL ); OfferDataNSeq res; IntSeq filterList( friendList ); filterList.push_back(userId); filterList.insert( filterList.end(), applyList.begin(), applyList.end() ); sort( filterList.begin(), filterList.end() ); int ipLimit = 1; xce::friendfinder::IPNoteSeq ipSeq = OfferFriendsUtil::getFreqIP(userId, ipLimit); int base_weight = 0; map<int,int>::const_iterator weiIt = weights.find(BaseTypeIPSame); if( weiIt!=weights.end() ) base_weight = weiIt->second; vector<int> ipFriends; createDetail << " ip_"; if( !ipSeq.empty() ) { ipFriends = OfferFriendsUtil::getUsersWithMaskByIP( ipSeq.at(0).ip, ipFriendLimit, filterList ); /* char chrLongValue[30]; sprintf(chrLongValue, "%lu", ipSeq.at(0).ip); */ for(vector<int>::iterator iter=ipFriends.begin(); iter!=ipFriends.end(); ++iter){ OfferDataN ipFriend; ipFriend.userId = *iter; ipFriend.weight = base_weight; //ipFriend.infos.insert(pair<int, string>(BaseTraitIPSame, string(chrLongValue))); ipFriend.sign = ((int)0) | (((int)1)<<BaseTraitIPSame); res.push_back(ipFriend); createDetail << ipFriend.userId << "_"; } createLog << " ipFriends(" << ipSeq.at(0).ip << ")(" << ipFriends.size() << ")"; } else { createLog << " ipFriends(0)(" << ipFriends.size() << ")"; } gettimeofday( &tvIP, NULL ); double linIPStart = ((double)tvStart.tv_sec*1000000 + (double)tvStart.tv_usec); double linIPEnd = ((double)tvIP.tv_sec*1000000 + (double)tvIP.tv_usec); double linIPTime = linIPEnd - linIPStart; linIPTime = linIPTime/1000000; createLog << "(" << linIPTime << "s)"; return res; }
OfferDataNSeq OfferCacheDataI::doOnlineFilter( GetInfo& info,const OfferDataNSeq& sourceOffers,int limit,const std::map<int,bool>& onlinestates ){ if( sourceOffers.empty() || limit <= 0 ){ return sourceOffers; } OfferDataNSeq ret_online; OfferDataNSeq ret_offline; for(OfferDataNSeq::const_iterator iter=sourceOffers.begin(); iter!=sourceOffers.end(); ++iter){ map<int,bool>::const_iterator it = onlinestates.find( iter->userId ); if( it != onlinestates.end() && it->second ){ ret_online.push_back( *iter ); } else{ ret_offline.push_back( *iter ); } } OfferDataNSeq ret; for(OfferDataNSeq::const_iterator iter=ret_online.begin(); iter!=ret_online.end(); ++iter){ ret.push_back(*iter); if( --limit <= 0 ) break; } info.onlineRes= ret.size(); if( limit <= 0 ){ info.offerRes = 0; return ret; } ret_offline = doRandom( ret_offline,ret_offline.size() ); int count = 0; for( OfferDataNSeq::const_iterator iter=ret_offline.begin(); iter!=ret_offline.end(); ++iter ){ ret.push_back(*iter); if( ++count == limit ) break; } info.offerRes = count; return ret; }
OfferDataNSeq OfferCacheDataI::doRandom( const OfferDataNSeq& sourceOffers, int limit ){ OfferDataNSeq ret; int value_sum = 0; //随机取好友 vector<int> posSequence; vector<bool> hitSequence; for(OfferDataNSeq::const_iterator iter=sourceOffers.begin(); iter!=sourceOffers.end(); ++iter){ value_sum += iter->weight; posSequence.push_back(iter->weight); hitSequence.push_back(false); } if( sourceOffers.empty() || value_sum <= 0 || limit <=0 ){ return ret; } int loop_count = (int)sourceOffers.size() <= limit ? (int)sourceOffers.size() : limit; while( --loop_count >= 0 ){ int randValue = rand() % value_sum; int value_plus = 0; for(size_t pos=0; pos<posSequence.size(); ++pos){ if( hitSequence[pos] ){ continue; } value_plus += posSequence[pos]; if( value_plus - randValue >= 0 ) { hitSequence[pos] = true; value_sum -= posSequence[pos]; ret.push_back( sourceOffers[pos] ); break; } } } return ret; }
void BackendData::add(int type, const OfferDataNSeq& offers) { MCE_INFO("[BackendData] ada type(" << type << ") offers size(" << offers.size() << ")"); IceUtil::Mutex::Lock lock(*this); map<int, OfferDataNSeq>::iterator it = _typedOfferDataNSeq.find( type ); if(it == _typedOfferDataNSeq.end()){ pair<map<int, OfferDataNSeq>::iterator, bool> insRes = _typedOfferDataNSeq.insert(make_pair(type,offers)); //it = insRes.first; } }
OfferDataNSeq OfferCacheDataI::getBest(GetInfo& info, const std::map<int,bool>& onlinestates, int limit) { info.hit = true; info.limit = limit; info.bestCount = bestOffers.size(); info.offerCount = offers.size(); OfferDataNSeq orderedOffers; { IceUtil::Mutex::Lock lock(_mutex); if( limit < 0 || (int)(bestOffers.size()+offers.size()) <= limit ) { orderedOffers = bestOffers; info.bestRes = bestOffers.size(); OfferDataNSeq tmp = doOnlineFilter( info,offers,offers.size(),onlinestates ); orderedOffers.insert( orderedOffers.end(), tmp.begin(), tmp.end() ); } else if( limit <= (int)bestOffers.size() ) { orderedOffers = OfferDataNSeq( bestOffers.begin(), bestOffers.begin()+limit ); info.bestRes = limit; info.onlineRes = 0; info.offerRes = 0; } else{ // bestOffers.size() < limit < bestOffers.size()+offers.size() orderedOffers = bestOffers; OfferDataNSeq tmp = doOnlineFilter( info,offers,limit-(int)bestOffers.size(),onlinestates ); orderedOffers.insert( orderedOffers.end(), tmp.begin(), tmp.end() ); info.bestRes = bestOffers.size(); } } info.timeout = (long)((int)time(NULL)-_timeStamp); return orderedOffers; }
OfferDataNSeq BackendProducer::createFromCommonFriend(int userId, int commFriendLimit, const std::map<int, int>& weights, const MyUtil::IntSeq& applyList, const MyUtil::IntSeq& friendList, const MyUtil::IntSeq& blockList, const MyUtil::IntSeq& commBlockList, std::ostringstream& createLog, std::ostringstream& createDetail) { struct timeval tvStart, tvComm; gettimeofday( &tvStart, NULL ); OfferDataNSeq res; com::xiaonei::service::CommonFriendSeq commonFriends; com::xiaonei::service::CommonFriendSeq tmpCommon; // commonFriends = OfferFriendsUtil::calCommonFriend(userId, applyList, friendList, blockList, commBlockList, commFriendLimit); commonFriends = OfferFriendsUtil::calFoFCommonFriend(userId, applyList, friendList, blockList, commBlockList, commFriendLimit); MCE_INFO("[BackendProducer] create CommonFriend userId:" << userId << " offer new FoF CommonFriend size:" << commonFriends.size()); if(commonFriends.size() < commFriendLimit) { tmpCommon = OfferFriendsUtil::calCommonFriend(userId, applyList , friendList, blockList, commBlockList, commFriendLimit - commonFriends.size()); commonFriends.insert(commonFriends.end(), tmpCommon.begin(), tmpCommon.end()); } MCE_INFO("[BackendProducer] create CommonFriend userId:" << userId << " offer old CommonFriend size:" << tmpCommon.size()); vector<int> commonIdSeq; for (vector<com::xiaonei::service::CommonFriend>::const_iterator iter = commonFriends.begin(); iter != commonFriends.end(); ++iter) { commonIdSeq.push_back(iter->userId); } Int2IntMap commonIdMap = OfferFriendsUtil::getFriendCountBatch(commonIdSeq); //何必呢?? int base_weight = 0; std::map<int, int>::const_iterator weiIt = weights.find(BaseTypeCommonFriend); if (weiIt != weights.end()) { base_weight = weiIt->second; } createDetail << " comms_"; for (vector<com::xiaonei::service::CommonFriend>::const_iterator commonIt = commonFriends.begin(); commonIt != commonFriends.end(); ++commonIt) { Int2IntMap::const_iterator fIt = commonIdMap.find(commonIt->userId); short ffSize; //这个干嘛了?? if (fIt == commonIdMap.end()) { ffSize = 1; continue; } ffSize = (short)fIt->second; OfferDataN commFriend; commFriend.userId = commonIt->userId; short sameElementSize = (short)commonIt->shares.size(); commFriend.weight = base_weight; commFriend.sign = ((int)0) | (((int)1) << BaseTraitCommonFriend); res.push_back(commFriend); createDetail << commFriend.userId << "_"; } gettimeofday( &tvComm, NULL ); double linCommStart = ((double)tvStart.tv_sec*1000000 + (double)tvStart.tv_usec); double linCommEnd = ((double)tvComm.tv_sec*1000000 + (double)tvComm.tv_usec); double linCommTime = linCommEnd - linCommStart; linCommTime = linCommTime/1000000; createLog << " commonFriends(" << commonFriends.size() << ")(" << linCommTime << "s)"; return res; }