public IDMultisetItemList PotentialFriendsPLinq(SubscriberID id, int maxCandidates) { var candidates = subscribers[id].Friends.AsParallel() // Map .SelectMany(friend => subscribers[friend].Friends) .Where(foaf => foaf != id && !(subscribers[id].Friends.Contains(foaf))) // remove self, own friends .GroupBy(foaf => foaf) // Reduce .Select(foafGroup => new IDMultisetItem(foafGroup.Key, foafGroup.Count())); return(Multiset.MostNumerous(candidates, maxCandidates)); // postprocess results of Reduce }
public IDMultisetItemList PotentialFriendsParallel(SubscriberID id, int maxCandidates) { object locker = new object(); IDMultiset candidates = new IDMultiset(); Parallel.ForEach(subscribers[id].Friends, // Map over friends () => Multiset.Create(new HashSet <SubscriberID>()), // init thread-local state localFoafs with empty Multiset (friend, loopState, localFoafs) => { var foafs = subscribers[friend].FriendsCopy(); foafs.RemoveWhere(foaf => foaf == id || subscribers[id].Friends.Contains(foaf)); // remove self, own friends return(Multiset.Union(localFoafs, Multiset.Create(foafs))); // Reduce, thread-local }, localFoafs => { lock (locker) candidates = Multiset.Union(localFoafs, candidates); }); // Reduce, among threads return(Multiset.MostNumerous(candidates, maxCandidates)); // postprocess results of Reduce }
public IDMultisetItemList PotentialFriendsSequential(SubscriberID id, int maxCandidates) { // Map var foafsList = new List <IDMultiset>(); foreach (SubscriberID friend in subscribers[id].Friends) { var foafs = subscribers[friend].FriendsCopy(); foafs.RemoveWhere(foaf => foaf == id || subscribers[id].Friends.Contains(foaf)); // remove self, own friends foafsList.Add(Multiset.Create(foafs)); } // Reduce IDMultiset candidates = new IDMultiset(); foreach (IDMultiset foafs in foafsList) { candidates = Multiset.Union(foafs, candidates); } // Postprocess return(Multiset.MostNumerous(candidates, maxCandidates)); }