예제 #1
0
        public StateSnapshot Update(ConnectionState?simulateConnection)
        {
            Dictionary <PeerGroupState, List <LocationState> > mapCopy;

            lock (this.mapLock)
            {
                mapCopy = new Dictionary <PeerGroupState, List <LocationState> >(this.peerGroupToLocationsMap);
            }

            DateTime        utcNow  = DateTime.UtcNow;
            ParallelOptions options = new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount / 2
            };

            Parallel.ForEach(mapCopy, options, pair => pair.Key.Update(utcNow, pair.Value, simulateConnection));

            StateSnapshot result = new StateSnapshot(utcNow, mapCopy.Count);

            foreach (var pair in mapCopy)
            {
                PeerGroupState managedPeerGroup  = pair.Key;
                PeerGroupState snapshotPeerGroup = managedPeerGroup.ShallowCopy();

                List <LocationState>  managedLocations  = pair.Value;
                IList <LocationState> snapshotLocations = managedLocations.Select(l => l.ShallowCopy()).ToArray();

                result.Add(snapshotPeerGroup, snapshotLocations);
            }

            this.LastUpdated = utcNow;
            return(result);
        }
예제 #2
0
        private void UpdateStatusRows(StateSnapshot states)
        {
            HashSet <Guid> currentLocations = new HashSet <Guid>(this.statusRowMap.Comparer);

            foreach (var pair in states.AllPeerGroupLocations)
            {
                PeerGroupState peerGroupState = pair.Key;
                foreach (LocationState locationState in pair.Value)
                {
                    Guid locationId = locationState.Location.Id;
                    currentLocations.Add(locationId);

                    if (this.statusRowMap.TryGetValue(locationId, out StatusRow row))
                    {
                        row.Update(peerGroupState, locationState);
                    }
                    else
                    {
                        row = new StatusRow();
                        row.Update(peerGroupState, locationState);
                        this.statusRows.Add(row);
                        this.statusRowMap.Add(locationId, row);
                    }
                }
            }

            foreach (var pair in this.statusRowMap.Where(pair => !currentLocations.Contains(pair.Key)).ToArray())
            {
                this.statusRows.Remove(pair.Value);
                this.statusRowMap.Remove(pair.Key);
            }
        }
예제 #3
0
        private void UpdatePeerGroups(NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
            case NotifyCollectionChangedAction.Add:
                foreach (PeerGroup peerGroup in e.NewItems)
                {
                    this.GetPeerGroupState(peerGroup);
                }

                break;

            case NotifyCollectionChangedAction.Remove:
                foreach (PeerGroup peerGroup in e.OldItems)
                {
                    if (this.FindPeerGroupState(peerGroup, out PeerGroupState state))
                    {
                        this.PeerGroups.Remove(state);
                    }
                }

                break;

            case NotifyCollectionChangedAction.Replace:
                foreach (var pair in e.OldItems.Cast <PeerGroup>().Zip(e.NewItems.Cast <PeerGroup>(), (o, n) => Tuple.Create(o, n)))
                {
                    if (this.FindPeerGroupState(pair.Item1, out PeerGroupState oldState))
                    {
                        PeerGroupState newState = this.GetPeerGroupState(pair.Item2, allowAdd: false);
                        int            index    = this.PeerGroups.IndexOf(oldState);
                        this.PeerGroups[index] = newState;
                    }
                }

                break;

            case NotifyCollectionChangedAction.Move:
                // We don't care about the profile's PeerGroup positions.
                break;

            default:                     // NotifyCollectionChangedAction.Reset
                foreach (PeerGroup peerGroup in this.profile.PeerGroups)
                {
                    this.GetPeerGroupState(peerGroup);
                }

                foreach (PeerGroupState state in this.PeerGroups.ToList())
                {
                    if (!this.profile.PeerGroups.Contains(state.PeerGroup))
                    {
                        this.PeerGroups.Remove(state);
                    }
                }

                break;
            }
        }
예제 #4
0
        private PeerGroupState GetPeerGroupState(PeerGroup peerGroup, bool allowAdd = true)
        {
            if (!this.FindPeerGroupState(peerGroup, out PeerGroupState result))
            {
                result = new PeerGroupState(peerGroup);
                if (allowAdd)
                {
                    this.PeerGroups.Add(result);
                }
            }

            return(result);
        }
예제 #5
0
 private bool FindPeerGroupState(PeerGroup peerGroup, out PeerGroupState state)
 {
     state = this.PeerGroups.FirstOrDefault(s => s.PeerGroup == peerGroup);
     return(state != null);
 }
예제 #6
0
 internal void Add(PeerGroupState snapshotPeerGroup, IEnumerable <LocationState> snapshotLocations)
 => this.states.Add(snapshotPeerGroup, snapshotLocations);