public (DepartmentVisitStatus, List <List <int> >) Query(int deptId)
        {
            if (deptId < 1 || deptId > deptCount)
            {
                throw new ArgumentException("Department ID should be within the [1; deptCount] range");
            }

            DepartmentVisitStatus visitStatus  = DepartmentVisitStatus.Unvisited;
            List <List <int> >    uniqueVisits = null;

            List <string> record = dao.GetDeptRecord(deptId);

            visitStatus = (DepartmentVisitStatus)Enum.Parse(typeof(DepartmentVisitStatus), record[0]);

            uniqueVisits = new List <List <int> >();
            for (int i = 1; i < record.Count; ++i)
            {
                List <int> uniqueVisit = new List <int>();

                string line = record[i];
                for (int j = 0; j < line.Length; ++j)
                {
                    if (line[j] == '1')
                    {
                        uniqueVisit.Add(j + 1);
                    }
                }

                uniqueVisits.Add(uniqueVisit);
            }

            return(visitStatus, uniqueVisits);
        }
Esempio n. 2
0
        public DepartmentArrangement Build()
        {
            if (!IsValidDeptId(StartDept) || !IsValidDeptId(FinishDept))
            {
                throw new Exception("Start and finish departments should be initialized before building");
            }
            for (int i = 0; i < DeptCount; ++i)
            {
                if (depts[i] == null)
                {
                    throw new Exception("All departments should be initialized before building");
                }
            }

            VisitsDAO dao = new VisitsDAO(DeptCount);

            List <DepartmentVisitStatus> visitStatuses = new List <DepartmentVisitStatus>();

            for (int i = 0; i < DeptCount; ++i)
            {
                visitStatuses.Add(DepartmentVisitStatus.Unvisited);
            }

            // precalc query results

            int nextDept = StartDept;
            List <(int, int)> visitRecord = new List <(int, int)>(); // (department id, unique stamp sheet state id)
            BitArray          stamps      = new BitArray(StampCount);

            while (nextDept != FinishDept)
            {
                List <string> uniqueVisits = dao.GetDeptRecord(nextDept);

                if (uniqueVisits == null)
                {
                    throw new Exception("Filesystem access failed");
                }

                string stampRecord = BitArrayToString(stamps);

                bool infiniteLoop = false;
                for (int i = 0; i < uniqueVisits.Count; ++i)
                {
                    if (stampRecord.Equals(uniqueVisits[i]))
                    {
                        infiniteLoop = true;

                        int loopStart = visitRecord.IndexOf((nextDept, i));
                        for (int j = loopStart; j < visitRecord.Count; ++j)
                        {
                            visitStatuses[visitRecord[j].Item1 - 1] = DepartmentVisitStatus.InfiniteLoop;
                        }

                        break;
                    }
                }
                if (infiniteLoop)
                {
                    break;
                }

                visitStatuses[nextDept - 1] = DepartmentVisitStatus.Visited;
                visitRecord.Add((nextDept, uniqueVisits.Count));
                dao.AddDeptVisit(nextDept, stampRecord);

                nextDept = depts[nextDept - 1].SetStampsAndGetNext(stamps);
            }

            if (nextDept == FinishDept)
            {
                visitStatuses[nextDept - 1] = DepartmentVisitStatus.Visited;
                dao.AddDeptVisit(nextDept, BitArrayToString(stamps));
            }

            // prepare files for queries

            for (int i = 1; i <= DeptCount; ++i)
            {
                List <string> uniqueVisits = dao.GetDeptRecord(i);

                if (uniqueVisits == null)
                {
                    throw new Exception("Filesystem access failed");
                }

                List <string> uniqueProcessedVisits = new List <string>();

                foreach (string stampRecord in uniqueVisits)
                {
                    BitArray recordedStamps = new BitArray(stampRecord.Length);

                    for (int j = 0; j < recordedStamps.Length; ++j)
                    {
                        recordedStamps[j] = (stampRecord[j] == '1');
                    }

                    depts[i - 1].SetStampsAndGetNext(recordedStamps);

                    uniqueProcessedVisits.Add(BitArrayToString(recordedStamps));
                }

                uniqueProcessedVisits = uniqueProcessedVisits.Distinct().ToList();

                dao.FinalizeDeptRecord(i, visitStatuses[i - 1], uniqueProcessedVisits);
            }

            return(new DepartmentArrangement(DeptCount, dao));
        }