public void Allocate(Link link) { if (state != State.FREE) throw new ApplicationException("Cannot reserve not free slot"); state = State.TAKEN; slotOWner = link; }
public void AllocatePath(Link link) { if (currCapacity < link.capacityNeeded) throw new ApplicationException("cannot allocate link!"); if (allocatedLinks.Exists(x => x == link)) throw new ApplicationException("link already exists!"); allocatedLinks.Add(link); currCapacity -= link.capacityNeeded; }
public void AllocateSlot(Link link, int slot) { List<int> neededSlots = GetNeededSlotsForLinkAndBeginPosition(link, slot); foreach(int slotNo in neededSlots) //TODO: refactor - use .foreach { if (!slots[slotNo].IsAvailable()) throw new ApplicationException("cannot allocate taken slot"); slots[slotNo].Allocate(link); } }
public void DeallocatePath(Link link) { if (!allocatedLinks.Remove(link)) throw new ApplicationException("link not exists!"); currCapacity += link.capacityNeeded; }
public void DeallocateSlot(Link link, int slot) { List<int> neededSlots = GetNeededSlotsForLinkAndBeginPosition(link, slot); neededSlots.ForEach(x => slots[x].Deallocate()); }
private List<Connection> FindShortestReversedPathForLinkAndGivenDestination(Link link, Device source, Device destination) { Device currDev = destination; List<Connection> path = new List<Connection>(); while (currDev != source) { Connection currPath = currDev.outgoingConnections.Find(x => x.destination.mark == currDev.mark - 1); if (currPath == null) throw new ApplicationException("dsadsads"); path.Add(currPath); currDev = currPath.destination; } path.Reverse(); return path; }
private void ValidateLinkPaths(Link link) { VerifyPathsSize(link); VerifyPathsSourceAndDestination(link); CheckPathsConsistency(link); CheckIfLinkIsAllocatedOnAllItsPathConnections(link); CheckIfEveryConnectionInWholePathIsUnique(link); }
private static void VerifyPathsSize(Link link) { if (link.mainPath.Count == 0) throw new PathValidationException("Path size is 0!"); if (link.additionalDestinationPaths.Count != link.additionalDestinations.Count) throw new PathValidationException("Not all additional destination paths are calculated"); if (link.additionalDestinationPaths.Any(x => x.Count == 0)) throw new PathValidationException("Additional destination path size is 0!"); if (link.additionalSourcePaths.Count != link.additionalSourcePaths.Count) throw new PathValidationException("Not all additional source paths are calculated"); if (link.additionalSourcePaths.Any(x => x.Count == 0)) throw new PathValidationException("Additional source path size is 0!"); }
private List<Connection> FindShortestPathForLinkAndGivenDestination(Link link, Device source, Device destination) { Device currDev = destination; List<Connection> path = new List<Connection>(); while (currDev != source) { Connection currPath = currDev.incomingConnections.Find(x => x.source.mark == currDev.mark - 1); path.Add(currPath); currDev = currPath.source; } path.Reverse(); return path; }
private void CheckIfEveryConnectionInWholePathIsUnique(Link link) { if (link.wholePath.Distinct().ToList().Count != link.wholePath.Count) throw new ApplicationException("Whole path connections are not distinct!"); }
private static void CheckIfLinkIsAllocatedOnAllItsPathConnections(Link link) { if (!link.wholePath.All(x => x.IsLinkAllocated(link))) throw new PathValidationException("Path is not allocated on all its connections!"); }
private void AllocateLinkPath(Link link) { AllocateMainPath(link); AllocateAdditionalPaths(link); ValidateLinkPaths(link); }
private void AllocateMainPath(Link link) { CreateMarksWithBFS(link, link.mainSource); if (link.mainDestination.mark == NOT_SEEN) throw new ApplicationException("Path allocation algirithm cannot allocate a link: " + link.name); if (link.mainPath != null) throw new ApplicationException("main path should be empty in this moment!"); List<Connection> path = FindShortestPathForLinkAndGivenDestination(link, link.mainSource, link.mainDestination); path.ForEach(x => x.AllocatePath(link)); link.mainPath = path; }
private void AllocateAdditionalSourcesPaths(Link link) { foreach (Device source in link.additionalSources) { CreateMarksWithBFS(link, source); int minMark = link.devicesOnWholePath.Min(x => x.mark); if (minMark == int.MaxValue) throw new ApplicationException("Path allocation algoritithm cannot allocate additional source for link: " + link.name); Device devWithMinMark = link.devicesOnWholePath.Find(x => x.mark == minMark); List<Connection> additionalSourcePath = FindShortestPathForLinkAndGivenDestination(link, source, devWithMinMark); additionalSourcePath.ForEach(x => x.AllocatePath(link)); link.additionalSourcePaths.Add(additionalSourcePath); } }
private void AllocateAdditionalPaths(Link link) { AllocateAdditionalSourcesPaths(link); AllocateAdditionalDestinationPaths(link); }
private static void VerifyPathsSourceAndDestination(Link link) { VerifyPathSource(link.mainPath, link.mainSource); VerifyPathDestination(link.mainPath, link.mainDestination); for (int i = 0; i < link.additionalSources.Count; i++) { VerifyPathSource(link.additionalSourcePaths[i], link.additionalSources[i]); } for (int i = 0; i < link.additionalDestinations.Count; i++) { VerifyPathDestination(link.additionalDestinationPaths[i], link.additionalDestinations[i]); } }
/// <summary> /// /// </summary> /// <param name="link"></param> /// <param name="slot"></param> /// <returns>EMPTY LIST MEANS IMPOSSIBLE - BUGFIX</returns> public List<int> GetNeededSlotsForLinkAndBeginPosition(Link link, int slot) { int currSlot = slot * maxCapacity / link.maxCapacityOnPath; int currModulo = slots.Count; int currConnectionModuloForLink = maxCapacity / link.capacityNeeded; int noOfAllocatedSlots = currModulo / currConnectionModuloForLink; List<int> neededSlots = new List<int>(); for (int i = currSlot; i < currModulo; i += currConnectionModuloForLink) { neededSlots.Add(i); } return neededSlots; }
public bool CanAllocateLink(Link link) { return currCapacity >= link.capacityNeeded; }
public bool IsLinkAllocated(Link link) { return allocatedLinks.Any(x => x == link); }
/// <summary> /// Comparation in decreasing order of capacity needed and then in dst.name order. /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <returns></returns> public int LinkCmp(Link lhs, Link rhs) { if (lhs.capacityNeeded > rhs.capacityNeeded) return -1; if (lhs.capacityNeeded < rhs.capacityNeeded) return 1; return String.CompareOrdinal(rhs.mainDestination.name, lhs.mainDestination.name); }
private void CheckNumberOfAllocatedSlots(Link link) { foreach (Connection connection in link.mainPath) { int neededSlotsOnConnection = link.capacityNeeded / connection.CapacityPerSlot; int slotsAllocatedOnConnection = connection.slots.Count(x => x.slotOWner == link); if (neededSlotsOnConnection != slotsAllocatedOnConnection) throw new PathValidationException("Slots number allocated on connection is wrong"); } }
private static void CheckPathsConsistency(Link link) { CheckPathConsistency(link.mainPath); link.additionalSourcePaths.ForEach(CheckPathConsistency); link.additionalDestinationPaths.ForEach(CheckPathConsistency); }
public bool CanAllocateSlot(Link link, int slot) { List<int> neededSlots = GetNeededSlotsForLinkAndBeginPosition(link, slot); return CanAllocateSlots(neededSlots); }
/// <summary> /// reversed BFS uses one-way links in reversed direction /// (uses incoming connections instead of outgoing connections) /// </summary> /// <param name="link"></param> /// <param name="destination"></param> private void CreateMarksWithReversedBFS(Link link, Device startPoint) { Queue<Device> frontier = new Queue<Device>(); frontier.Enqueue(startPoint); ResetMarks(NOT_SEEN); startPoint.mark = START_POINT; while (frontier.Count != 0) { Device curr = frontier.Dequeue(); foreach (Connection c in curr.incomingConnections) { if (c.source.mark == NOT_SEEN && c.CanAllocateLink(link)) { c.source.mark = curr.mark + 1; frontier.Enqueue(c.source); } } } }