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)); }
internal DepartmentArrangement(int deptCount, VisitsDAO dao) { this.deptCount = deptCount; this.dao = dao; }