/// <summary> /// perform the operation associated with this call /// </summary> /// <param name="initEdgeName">string:: the name of the edge</param> /// <exception cref="AbandonedMutexException" >thrown when the mutex is null</exception> /// <exception cref="InvalidOperationException" >thrown when EdgesCollection is uninitialized</exception> /// <exception cref="KeyNotFoundException" >thrown when the edge name does not exist.</exception> /// <exception cref="NullReferenceException" >thrown when the edge State is null</exception> /// <exception cref="TimeoutException" >thrown when obtaining the mutex times out</exception> public void TraverseEdgeReverse(string initEdgeName) { if (_mtxEdgesCollection == null) { string exceptionMsg = $"The edge {initEdgeName} could not be retrieved because the mutex has been abanoned."; throw new AbandonedMutexException(exceptionMsg); } CheckEdgesCollection(); if (!_mtxEdgesCollection.WaitOne(_mtxTimeout)) { // timed out waiting for the mutex string exceptionMsg = $"The edge {initEdgeName} could not be retrieved because a lock could not be obtained."; throw new TimeoutException(exceptionMsg); } try { string scrubbedEdgeName = _stringUtility.ScrubName(initEdgeName); if (!EdgesCollection.ContainsKey(scrubbedEdgeName)) { throw new KeyNotFoundException($"Edge {scrubbedEdgeName} not found on Node {Name}."); } IEdge foundEdge = EdgesCollection[scrubbedEdgeName]; foundEdge.Reverse(this); } finally { _mtxEdgesCollection.ReleaseMutex(); } }
/// <summary> /// Creates new instance of <see cref="AdjacencyMatrix"/> /// </summary> /// <param name="graph">graph</param> public AdjacencyMatrix(Graph graph) : base(graph.Vertices.Count) { // setting fields this.vertices = graph.Vertices; this.edges = graph.Edges; // constructing graph adjacency matrix this.ConstructAdjacencyMatrix(); }
/// <summary> /// INTERNAL Deletes edges that terminate at a given node /// </summary> /// <param name="initNodeName">string:: the node name</param> /// <exception cref="AbandonedMutexException" >thrown when the mutex is null</exception> /// <exception cref="ApplicationException" >thrown when the edge cannot be removed from the EdgesCollection</exception> /// <exception cref="ArgumentNullException" >thrown when the node name is null</exception> /// <exception cref="InvalidOperationException" >thrown when EdgesCollection is uninitialized</exception> /// <exception cref="TimeoutException" >thrown when obtaining the mutex times out</exception> /* internal */ void INodeInternal.DeleteEdgesTerminatingOnNode(string initNodeName) { if (string.IsNullOrWhiteSpace(initNodeName)) { throw new ArgumentNullException("initNodeName"); } if (_mtxEdgesCollection == null) { string exceptionMsg = $"The edges on node {initNodeName} could not be iterated because the mutex has been abanoned."; throw new AbandonedMutexException(exceptionMsg); } CheckEdgesCollection(); if (!_mtxEdgesCollection.WaitOne(_mtxTimeout)) { // timed out waiting for the mutex string exceptionMsg = $"The edges on node {initNodeName} could not be iterated because a lock could not be obtained."; throw new TimeoutException(exceptionMsg); } try { string scrubbedNodeName = _stringUtility.ScrubName(initNodeName); // make a list of those to be removed List <string> nameList = new List <string>(); foreach (string name in EdgesCollection.Keys) { IEdge edgeComponent = EdgesCollection[name]; if (edgeComponent.IsTerminalNode(scrubbedNodeName)) { nameList.Add(name); } } // remove the nodes that were found foreach (string name in nameList) { IEdge edgeComponent = null; EdgesCollection.TryRemove(name, out edgeComponent); if (edgeComponent != null) { edgeComponent.Dispose(); } } } finally { _mtxEdgesCollection.ReleaseMutex(); } return; }
/// <summary> /// INTERNAL deletes an edge /// </summary> /// <param name="initEdgeName">string:: the name of the edge</param> /// <exception cref="AbandonedMutexException" >thrown when the mutex is null</exception> /// <exception cref="ApplicationException" >thrown when the edge cannot be removed from EdgesCollection</exception> /// <exception cref="ArgumentNullException" >thrown when the edge name is null</exception> /// <exception cref="InvalidOperationException" >thrown when EdgesCollection is uninitialized</exception> /// <exception cref="TimeoutException" >thrown when obtaining the mutex times out</exception> /* internal */ void INodeInternal.DeleteEdge(string initEdgeName) { if (string.IsNullOrWhiteSpace(initEdgeName)) { throw new ArgumentNullException("initEdgeName"); } if (_mtxEdgesCollection == null) { string exceptionMsg = $"The edge {initEdgeName} could not be deleted because the mutex has been abanoned."; throw new AbandonedMutexException(exceptionMsg); } CheckEdgesCollection(); if (!_mtxEdgesCollection.WaitOne(_mtxTimeout)) { // timed out waiting for the mutex string exceptionMsg = $"The edge {initEdgeName} could not be deleted because a lock could not be obtained."; throw new TimeoutException(exceptionMsg); } try { string scrubbedEdgeName = _stringUtility.ScrubName(initEdgeName); if (!EdgesCollection.ContainsKey(scrubbedEdgeName)) { string exceptionText = $"Edge {scrubbedEdgeName} does not exist in EdgesCollection."; throw new KeyNotFoundException(exceptionText); } IEdge component = null; if (EdgesCollection.TryRemove(scrubbedEdgeName, out component)) { if (component != null) { component.Dispose(); } } else { string exceptionText = $"Edge {scrubbedEdgeName} could not be removed from node {Name} EdgesCollection."; throw new ApplicationException(exceptionText); } } finally { _mtxEdgesCollection.ReleaseMutex(); } return; }
/// <summary> /// accessor for the State of an edge /// </summary> /// <param name="initEdgeName">string:: edge name</param> /// <returns>object:: the State of an edge</returns> /// <exception cref="AbandonedMutexException" >thrown when the mutex is null</exception> /// <exception cref="ArgumentNullException" >thrown when the edge name parameter is null</exception> /// <exception cref="InvalidOperationException" >thrown when EdgesCollection is uninitialized</exception> /// <exception cref="KeyNotFoundException" >thrown when the edge name does not exist</exception> /// <exception cref="NullReferenceException" >thrown when the value in EdgesCollection is null</exception> /// <exception cref="TimeoutException" >thrown when obtaining the mutex times out</exception> public object GetEdgeState(string initEdgeName) { Object returnObject = null; if (string.IsNullOrWhiteSpace(initEdgeName)) { throw new ArgumentNullException("initEdgeName"); } if (_mtxEdgesCollection == null) { string exceptionMsg = $"The state of edge {initEdgeName} could not be retrieved because the mutex has been abanoned."; throw new AbandonedMutexException(exceptionMsg); } CheckEdgesCollection(); if (!_mtxEdgesCollection.WaitOne(_mtxTimeout)) { // timed out waiting for the mutex string exceptionMsg = $"The state of edge {initEdgeName} could not be retrieved because a lock could not be obtained."; throw new TimeoutException(exceptionMsg); } try { string scrubbedEdgeName = _stringUtility.ScrubName(initEdgeName); if (!EdgesCollection.ContainsKey(scrubbedEdgeName)) { string exceptionText = $"The edge {scrubbedEdgeName} on node {Name} does not exist in EdgesCollection."; throw new KeyNotFoundException(exceptionText); } IEdge edgeComponent = EdgesCollection[scrubbedEdgeName]; if (edgeComponent == null) { string exceptionText = $"The edge {scrubbedEdgeName} on node {Name} is null."; throw new NullReferenceException(exceptionText); } returnObject = edgeComponent.GetState(); } finally { _mtxEdgesCollection.ReleaseMutex(); } return(returnObject); }
private bool disposedValue = false; // To detect redundant calls /// <summary> /// dispose of managed and unmanaged objects /// </summary> /// <param name="disposing">bool:: true if called from code, false if called from finalizer</param> public void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { try { if (_mtxEdgesCollection != null) { // wait indefinitely _mtxEdgesCollection.WaitOne(); } if (_stringUtility != null) { _stringUtility.Dispose(); } if (EdgesCollection != null) { foreach (string key in EdgesCollection.Keys) { IEdge item = EdgesCollection[key]; if (item != null) { item.Dispose(); item = null; } } EdgesCollection.Clear(); EdgesCollection = null; } } finally { if (_mtxEdgesCollection != null) { _mtxEdgesCollection.ReleaseMutex(); _mtxEdgesCollection.Close(); // will be disposed when last handle is lost } } } disposedValue = true; } }
/// <summary> /// INTERNAL Create an edge with specific initialization of edge state /// </summary> /// <typeparam name="TEdge">The type of edge state. constraints - where TEdge : class, IEdgeState, IDisposable, new()</typeparam> /// <param name="initName">string:: name of the edge</param> /// <param name="initState">TEdge:: the initial State</param> /// <param name="initTerminalNode">INode:: the terminal node</param> /// <param name="initIsDirected">bool:: if true, it is directed, otherwise it is bidirectional</param> /// <returns>IEdge:: the created edge</returns> /// <exception cref="AbandonedMutexException" >thrown when the mutex is null</exception> /// <exception cref="ApplicationException" >thrown when the Edge cannot be added to EdgesCollection</exception> /// <exception cref="ArgumentException" >thrown when the edge name already exists</exception> /// <exception cref="InvalidOperationException" >thrown when the Edges Collection is uninitialized</exception> /// <exception cref="TimeoutException" >thrown when obtaining the mutex times out</exception> /* internal */ IEdge INodeInternal.CreateEdge <TEdge>(string initName, TEdge initState, INode initTerminalNode, bool initIsDirected) /* where TEdge : class, IDisposable, new() */ { IEdge returnValue = null; if (_mtxEdgesCollection == null) { string exceptionMsg = $"The edge {initName} could not be created because the mutex has been abanoned."; throw new AbandonedMutexException(exceptionMsg); } CheckEdgesCollection(); if (!_mtxEdgesCollection.WaitOne(_mtxTimeout)) { // timed out waiting for the mutex string exceptionMsg = $"The edge {initName} could not be created because a lock could not be obtained."; throw new TimeoutException(exceptionMsg); } try { string scrubbedName = _stringUtility.ScrubName(initName); if (EdgesCollection.ContainsKey(scrubbedName)) { string exceptionText = $"The edge {scrubbedName} already exists"; throw new ArgumentException(exceptionText); } returnValue = new Edge <TEdge>(scrubbedName, initState, initTerminalNode, initIsDirected); if (!EdgesCollection.TryAdd(scrubbedName, returnValue)) { string exceptionText = $"Edge {scrubbedName} could not be added to node {Name} EdgesCollection."; throw new ApplicationException(exceptionText); } } finally { _mtxEdgesCollection.ReleaseMutex(); } return(returnValue); }
/// <summary> /// Entry point /// </summary> /// <param name="args">arguments of programm</param> static void Main(string[] args) { try { // testing algorithm implementation Console.WriteLine("Input vertices separeted by comma."); // reading vertices input var verticesInput = Console.ReadLine(); var vertices = verticesInput.Split(new[] { ',' }) .Select(v => new Vertex { Number = int.Parse(v) }) .ToList(); Console.WriteLine("Input edges separated by comma in this way : v1 -> v2 length"); // reading edges input var edgesInput = Console.ReadLine(); var edges = edgesInput.Split(new[] { ',' }) .Select(e => { var input = e.Split(new[] { ' ' }); return(new Edge { First = new Vertex { Number = int.Parse(input[0]) }, Second = new Vertex { Number = int.Parse(input[2]) }, Direction = input[1] == "->" ? EdgeDirection.FromFirstToSecond : input[2] == "<-" ? EdgeDirection.FromSecondToFirst : EdgeDirection.Both, Length = int.Parse(input[3]) }); }) .ToList(); // constructing algoritm-specific structures var verticesCollection = new VerticesCollection(vertices); var edgesCollection = new EdgesCollection(verticesCollection, edges); // constructing graph var graph = new Graph { Vertices = verticesCollection, Edges = edgesCollection }; // constructing adjacency matrix var adjacencyMatrix = new AdjacencyMatrix(graph); // constructing algoritm instance var algorithm = new FWAlgorithm(adjacencyMatrix); // constructing printer for printing algorithm step matrices var printer = new Action <int, string, dynamic>((c, s, m) => { Console.WriteLine($"{s}{c}:"); var color = default(ConsoleColor); const string tab = "\t\t"; const string space = " "; for (var i = 0; i < m.Size; i++) { Console.Write(tab); for (var j = 0; j < m.Size; j++) { color = (ConsoleColor)m[i, j].Color; Console.ForegroundColor = color; Console.Write(m[i, j].Value.ToString().PadLeft(3)); Console.ResetColor(); Console.Write(space); } Console.WriteLine(); } Console.WriteLine(); }); // executing algorithm var count = 0; while (algorithm.Next()) { var step = algorithm.LastStep; printer.Invoke(count, "A", step.A); printer.Invoke(count, "B", step.B); count++; Console.Read(); } } catch (Exception ex) { // printing exception message Console.WriteLine(ex.Message); } finally { // finalizing Console.WriteLine("Hit <Enter> to close..."); Console.ReadLine(); Console.WriteLine("Closing..."); } }