public TopologyModel(TopologyModel tm)
        {
            tm.rwLock.EnterReadLock();

            try
            {
                containers = new Dictionary <DMSType, Dictionary <long, IdentifiedObject> >(tm.containers.Count);

                foreach (KeyValuePair <DMSType, Dictionary <long, IdentifiedObject> > container in tm.containers)
                {
                    containers.Add(container.Key, new Dictionary <long, IdentifiedObject>(container.Value));
                }

                analogInputs           = new ConcurrentDictionary <long, float>();
                discreteInputs         = new ConcurrentDictionary <long, int>();
                measurementsOfInterest = new HashSet <long>(tm.measurementsOfInterest);
                markedSwitchStates     = new ConcurrentDictionary <long, bool>(tm.markedSwitchStates);
                typeToModelCode        = ModelResourcesDesc.GetTypeToModelCodeMap();
                loadProfiles           = new List <DailyLoadProfile>(tm.loadProfiles);
                graph = tm.graph;
            }
            finally
            {
                tm.rwLock.ExitReadLock();
            }

            rwLock = new ReaderWriterLockSlim();
        }
        public TopologyModel(List <DailyLoadProfile> loadProfiles)
        {
            DMSType[] types = ModelResourcesDesc.TypeIdsInInsertOrder;
            containers = new Dictionary <DMSType, Dictionary <long, IdentifiedObject> >(types.Length);

            foreach (DMSType t in types)
            {
                containers.Add(t, new Dictionary <long, IdentifiedObject>());
            }

            rwLock                 = new ReaderWriterLockSlim();
            analogInputs           = new ConcurrentDictionary <long, float>();
            discreteInputs         = new ConcurrentDictionary <long, int>();
            measurementsOfInterest = new HashSet <long>();
            markedSwitchStates     = new ConcurrentDictionary <long, bool>();
            typeToModelCode        = ModelResourcesDesc.GetTypeToModelCodeMap();
            this.loadProfiles      = loadProfiles;
            graph = new TopologyGraph(containers, analogInputs, discreteInputs, markedSwitchStates, loadProfiles);
        }
        public bool ApplyUpdate(TopologyModelDownload download)
        {
            rwLock.EnterWriteLock();

            try
            {
                foreach (IdentifiedObject io in download.Inserted)
                {
                    DMSType type = ModelCodeHelper.GetTypeFromGID(io.GID);
                    Dictionary <long, IdentifiedObject> container;

                    if (!containers.TryGetValue(type, out container))
                    {
                        continue;
                    }

                    int oldCount = container.Count;
                    container[io.GID] = io;

                    if (container.Count != oldCount + 1)
                    {
                        return(false);
                    }

                    measurementsOfInterest.Add(io.GID);
                }

                foreach (IdentifiedObject io in download.Updated)
                {
                    DMSType type = ModelCodeHelper.GetTypeFromGID(io.GID);
                    Dictionary <long, IdentifiedObject> container;

                    if (!containers.TryGetValue(type, out container))
                    {
                        continue;
                    }

                    int oldCount = container.Count;
                    container[io.GID] = io;

                    if (container.Count != oldCount)
                    {
                        return(false);
                    }

                    measurementsOfInterest.Add(io.GID);
                }

                foreach (long gid in download.Deleted)
                {
                    DMSType type = ModelCodeHelper.GetTypeFromGID(gid);
                    Dictionary <long, IdentifiedObject> container;

                    if (!containers.TryGetValue(type, out container))
                    {
                        continue;
                    }

                    if (!container.Remove(gid))
                    {
                        return(false);
                    }

                    measurementsOfInterest.Remove(gid);
                    markedSwitchStates.TryRemove(gid, out _);
                }

                foreach (long switchGID in markedSwitchStates.Keys)
                {
                    if (!IsSwitchWithoutSCADA(switchGID))
                    {
                        markedSwitchStates.TryRemove(switchGID, out _);
                    }
                }

                graph = new TopologyGraph(containers, analogInputs, discreteInputs, markedSwitchStates, loadProfiles);

                return(true);
            }
            finally
            {
                rwLock.ExitWriteLock();
            }
        }