MyUtil::IntSeq RecommendData::getFriendsRecommendRandom(int limit) { IceUtil::Mutex::Lock lock(*this); checkTimeout(); IntSeq result; Int2IntMap friendRankMap; for (Int2IntSeqMap::iterator iter = _recommendMap.begin(); iter != _recommendMap.end(); ++iter) { if ( !iter->second.empty() ) { result.push_back( iter->first ); if ( _friendrank[ iter->first ] <= 0 ) { friendRankMap[ iter->first ] = 1; } else { friendRankMap[ iter->first ] = _friendrank[ iter->first ]; } } } if ( limit >= (int)friendRankMap.size() || limit < 0 ) { return result; } result.clear(); int sum = 0; vector<pair<int,int> > fr; for (map<int,int>::const_iterator iter = friendRankMap.begin(); iter != friendRankMap.end(); ++iter) { sum += iter->second; fr.push_back(*iter); } MCE_INFO("[RecommendData] getFriendsRecommendRandom ownerId(" << _ownerId << ") limit(" << limit << ") sum = " << sum); for (int i = 0; i < limit; ++i) { int r = 0; if (sum > 0) { r = rand() % sum; } else { MCE_WARN("[RecommendData] getFriendsRecommendRandom exception occur sum(" << sum << ")"); break; } for (vector<pair<int,int> >::iterator iter = fr.begin(); iter != fr.end(); ++iter) { r -= iter->second; if (r<=0) { result.push_back( iter->first ); sum -= iter->second; iter->second = 0; break; } } } return result; }
MyUtil::Int2IntSeqMap UserLoginData::getRecommendFriends(int userId) { IceUtil::RWRecMutex::RLock lock(_init_flag_mutex); MCE_INFO("[UserLoginData] getRecommendFriends userId(" << userId << ") _userLoginMap size(" << _userLoginMap.size() << ") ACTIVEDAYS(" << ACTIVEDAYS << ")"); struct timeval tvStart,tvEnd; double linStart = 0, linEnd = 0, lTime = 0; gettimeofday( &tvStart, NULL ); Int2IntSeqMap result; UserLoginMapType::iterator fIt = _userLoginMap.find(userId); if( fIt == _userLoginMap.end() || (int)fIt->second.count() < ACTIVEDAYS ) { //不是活跃用户 return result; } vector<int> friendList; try { friendList = BuddyByIdCacheAdapter::instance().getFriendListAsc(userId, -1); } catch ( Ice::Exception& e ) { MCE_WARN(time(NULL) << "[UserLoginData] getRecommendFriends BuddyByIdCacheAdapter Ice Exception : " << e.what() << "\n"); } catch ( ... ) { MCE_WARN(time(NULL) << "[UserLoginData] getRecommendFriends BuddyByIdCacheAdapter Unknow Exception"); } MCE_DEBUG("[UserLoginData] getRecommendFriends friendList size(" << friendList.size() << ")"); vector<int> negtiveFriendsList; for (vector<int>::iterator iter = friendList.begin(); iter != friendList.end(); ++iter) { if( _negtiveUserList.count(*iter) > 0 ) { negtiveFriendsList.push_back( *iter ); //找出不活跃的好友 } } if( negtiveFriendsList.empty() ) { return result; } Int2IntSeqMap friendsMap; try { friendsMap = BuddyByIdCacheAdapter::instance().getFriendLists( negtiveFriendsList ); } catch ( Ice::Exception& e ) { MCE_WARN(time(NULL) << "[UserLoginData] getRecommendFriends BuddyByIdCacheAdapter Ice Exception : " << e.what() << "\n"); } catch ( ... ) { MCE_WARN(time(NULL) << "[UserLoginData] getRecommendFriends BuddyByIdCacheAdapter Unknow Exception"); } MCE_DEBUG("[UserLoginData] getRecommendFriends negtiveFriendsList size(" << negtiveFriendsList.size() << ") friendsMap size(" << friendsMap.size() << ")"); vector<int> recommendFriend; ostringstream idPair; for (Int2IntSeqMap::iterator iter = friendsMap.begin(); iter != friendsMap.end(); ++iter) { recommendFriend = FriendFinderInfoCacheReplicaAdapter::instance().getGuestInfoMatchFriendList(userId, iter->first, -1); result[iter->first] = vector<int>(); idPair << "(" << iter->first << "," << recommendFriend.size() << ") "; for (vector<int>::iterator it = recommendFriend.begin(); it != recommendFriend.end(); ++it) { UserLoginMapType::iterator ff = _userLoginMap.find( *it ); if (ff == _userLoginMap.end() || (int)ff->second.count() < ACTIVEDAYS) { //过滤不活跃的推荐 continue; } vector<int>::iterator fIt = lower_bound( iter->second.begin(), iter->second.end(), *it ); //过滤好友列表 if (fIt == iter->second.end() || *fIt != *it) { result[iter->first].push_back( *it ); } } recommendFriend.clear(); } //AppendSingleRelationFriend(userId, result); //添加单向好友 Int2IntSeqMap blockFriends; IntSeq tmpVec; RelationBatchHelper::getBlockResult( userId, blockFriends); MCE_DEBUG("[UserLoginData] getRecommendFriends recommend Friends " << idPair.str() << " blockFriends size=" << blockFriends.size()); IntSeq recf; for (Int2IntSeqMap::iterator iter = blockFriends.begin(); //过滤block列表 iter != blockFriends.end(); ++iter) { recf = result[iter->first]; for (IntSeq::iterator it = recf.begin(); it != recf.end(); ++it) { if( find(iter->second.begin(), iter->second.end(), *it) == iter->second.end() ) { tmpVec.push_back( *it ); } } if( tmpVec.empty() ) { //如果没有可以推荐的人则不再出现该用户 result.erase( iter->first ); } else { result[iter->first] = tmpVec; } tmpVec.clear(); recf.clear(); } ostringstream idEmptySize; ostringstream idSize; for (Int2IntSeqMap::iterator iter = result.begin(); iter != result.end(); ++iter) { if (iter->second.empty()) { idEmptySize << iter->first << ", "; } else { idSize << "(" << iter->first << "," << iter->second.size() << ") "; } } //AppendUserFriends(result, friendList, friendsMap); for (Int2IntSeqMap::iterator iter=result.begin(); iter!=result.end(); ++iter) { //精简内存 IntSeq( iter->second ).swap( iter->second ); } gettimeofday( &tvEnd, NULL ); linStart = ((double)tvStart.tv_sec*1000000 + (double)tvStart.tv_usec); linEnd = ((double)tvEnd.tv_sec*1000000 + (double)tvEnd.tv_usec); lTime = linEnd - linStart; lTime = lTime/1000000; MCE_DEBUG("write :: " << idEmptySize.str() << " friend :: " << idSize.str() << " result size=" << result.size() << " cost time=" << lTime << "second!"); return result; }