- 
                Notifications
    You must be signed in to change notification settings 
- Fork 56
Class Graph
        Ori Roth edited this page Apr 2, 2017 
        ·
        3 revisions
      
    public class Graph<Data> implements Checkable { 
    /*
     * Type (4)
     */
        final Vertex<Data>[] vertices; 
        final Edge<Data>[] edges; 
        void invariant(); 
        void reset(); 
    /*
     * Nested types (3)
     */
        static class Edge<Data> implements Checkable, Comparable<Edge<Data>> { ... } 
        static class Vertex<Data> implements Comparable<Vertex<Data>> { ... } 
        static class Builder<Data> { ... } 
} Output types*: Comparable<Data>, Edge<Data>, Vertex<Data>.
public static class Graph.Edge<Data> implements Checkable, Comparable<Edge<Data>> { 
    /*
     * Type (4)
     */
        final Vertex<Data> from; 
        final Vertex<Data> to; 
        void invariant(); 
        int compareTo(Edge<Data> o); 
} Input types: Comparable<Data>.
Output types: Comparable<Data>, Vertex<Data>.
public static class Graph.Vertex<Data> implements Comparable<Vertex<Data>> { 
    /*
     * Type (9)
     */
        final Vertex<Data>[] to; 
        final Vertex<Data>[] from; 
        final Data data; 
        final int i; 
        void reset(); 
        void visit(); 
        boolean isVisited(); 
        String toString(); 
        final int compareTo(Vertex<Data> o); 
}*Input types: Comparable<Data>.
Output types: Comparable<Data>.
public static class Graph.Builder<Data> { 
    /*
     * Forge (1)
     */
        Builder(); 
    /*
     * Type (3)
     */
        void newEdge(Data from, Data to); 
        void newVertex(Data d); 
        Graph<Data> build(); 
} Input types: Comparable<Data>.
Output types: Comparable<Data>, Graph<Data>.
private static class Graph.Builder.Pair<Data> { 
    /*
     * Forge (1)
     */
        Pair(Data first, Data second); 
    /*
     * Type (2)
     */
        int hashCode(); 
        boolean equals(Object o); 
} // SSDLPedia
package il.ac.technion.cs.cs236700.graph;
import static il.ac.technion.cs.ssdl.utils.DBC.*;
import il.ac.technion.cs.ssdl.stereotypes.Classical;
import il.ac.technion.cs.ssdl.stereotypes.Immutable;
import il.ac.technion.cs.ssdl.stereotypes.Instantiable;
import il.ac.technion.cs.ssdl.utils.All;
import il.ac.technion.cs.ssdl.utils.DBC.Checkable;
import java.util.*;
/**
 * Class Graph: a class representing an immutable directed graph with
 * arbitrary data contained in its nodes. The design supports graph visitation,
 * with a facility to mark (and unmark) vertices as visited.
 * 
 * <Data> Kind of elements stored in each of the graph vertices. This
 *            data type must implement correctly both #equals(Object)
 *            and Comparable#compareTo(Object).
 * Author: Yossi Gil 
 * See:  20/06/2007
 */
@Instantiable @Immutable @Classical public class Graph<Data extends Comparable<Data>> implements Checkable {
    /**
     * An immutable array of all vertices of this graph
     */
    public final Vertex<Data>[] vertices;
    /**
     * An immutable array of all edges of this graph
     */
    public final Edge<Data>[] edges;
    
    public void invariant() {
        nonnull(vertices);
        nonnull(edges);
        sure(All.notNull(vertices));
        sure(All.notNull(edges));
        for (final Vertex<Data> v : vertices) {
            nonnull(v);
            sure(vertices[v.i] == v);
            for (final Vertex<Data> u : v.from) {
                nonnull(u);
                sure(Arrays.binarySearch(vertices, u) >= 0);
                sure(Arrays.binarySearch(u.to, v) >= 0);
            }
            for (final Vertex<Data> u : v.to) {
                nonnull(u);
                sure(Arrays.binarySearch(vertices, u) >= 0);
                sure(Arrays.binarySearch(u.from, v) >= 0);
            }
        }
        for (final Edge<Data> e : edges) {
            nonnull(e);
            nonnull(e.from);
            nonnull(e.to);
            sure(Arrays.binarySearch(vertices, e.from) >= 0);
            sure(Arrays.binarySearch(vertices, e.to) >= 0);
        }
    }
    
    /**
     * Mark all vertices of this graph unvisited
     */
    public void reset() {
        for (final Vertex<Data> v : vertices)
            v.reset();
    }
    
    private Graph(final Vertex<Data>[] vertices, final Edge<Data>[] edges) {
        nonnull(vertices);
        nonnull(edges);
        require(All.notNull(vertices));
        require(All.notNull(edges));
        this.vertices = vertices;
        this.edges = edges;
    }
    
    protected Graph(final Graph<Data> other) {
        this(other.vertices, other.edges);
    }
    
    /**
     * Class Graph.Edge: Represents an edge in a Graph.
     * 
     * <Data> the type of information stored in a graph node
     * Author: Yossi Gil 
 * See:  28/06/2007
     */
    public static class Edge<Data extends Comparable<Data>> implements Checkable, Comparable<Edge<Data>> {
        /**
         * where this edge starts
         */
        public final Vertex<Data> from;
        /**
         * where this edge ends
         */
        public final Vertex<Data> to;
        
        public void invariant() {
            nonnull(from);
            nonnull(to);
        }
        
        private Edge(final Vertex<Data> from, final Vertex<Data> to) {
            this.from = from;
            this.to = to;
        }
        
        public int compareTo(final Edge<Data> o) {
            final int $ = from.compareTo(o.from);
            return $ != 0 ? $ : to.compareTo(o.to);
        }
    }
    
    /**
     * Class Graph.Vertex: an immutable class representing a vertex in a
     * Graph
     * 
     * <Data> the type of information stored in each vertex.
     * Author: Yossi Gil 
 * See:  28/06/2007
     */
    public static class Vertex<Data extends Comparable<Data>> implements Comparable<Vertex<Data>> {
        /**
         * Vertices to which there is an edge from this vertex.
         */
        public final Vertex<Data> to[];
        /**
         * Vertices from which there is an edge leading to this vertex.
         */
        public final Vertex<Data> from[];
        /**
         * The data stored in this node.
         */
        public final Data data;
        /**
         * The ordinal number of this node in its containing graph.
         */
        public final int i;
        /**
         * Was this node visited?
         */
        private boolean visited;
        
        private Vertex(final Vertex<Data>[] from, final Vertex<Data>[] to, final Data attributes, final int i) {
            this.from = from;
            this.to = to;
            this.data = attributes;
            this.i = i;
        }
        
        /**
         * Reset this vertex. That is, the visited flag is set to
         * false.
         */
        public void reset() {
            visited = false;
        }
        
        /**
         * Marks this instance as visited. That is, the visited flag becomes
         * true.
         */
        public void visit() {
            visited = true;
        }
        
        /**
         * check the visitation status.
         * 
         * Return: true if this vertex was visited.
         */
        public boolean isVisited() {
            return visited;
        }
        
        /**
         * Returns toString() of the attributes and the number of
         * incoming and outgoing arcs.
         */
        @Override public String toString() {
            String $ = data == null ? super.toString() : data.toString();
            $ += " [" + from.length + " in, ";
            $ += to.length + " out]";
            return $;
        }
        
        public final int compareTo(final Vertex<Data> o) {
            nonnull(data);
            nonnull(o);
            nonnull(o.data);
            return data.compareTo(o.data);
        }
    }
    
    /**
     * Class Graph.Builder: A class to create a Graph from a
     * bunch of associations. The associations are added incrementally, with
     * function {@link #newEdge(Comparable, Comparable)} called for each
     * association, then function #build() is invoked to actually create
     * the graph. Vertices are created implicitly, i.e., the graph has only
     * vertices which participated in an association.
     * 
     * Author: Yossi Gil 
 * See:  20/06/2007
     * <Data> Kind of information stored in graph vertices
     */
    public static class Builder<Data extends Comparable<Data>> {
        private final HashSet<Pair<Data>> edges = new HashSet<Pair<Data>>();
        
        /**
         * Record an association between two data elements- later to be shown as
         * a graph edge.
         * 
         * from association starts here
         * to association ends here
         */
        public void newEdge(final Data from, final Data to) {
            nonnull(from);
            nonnull(to);
            newVertex(from);
            newVertex(to);
            edges.add(new Pair<Data>(from, to));
        }
        
        public void newVertex(final Data d) {
            nonnull(d);
            vertices.put(d, emptyPair());
        }
        
        private final TreeMap<Data, Pair<HashSet<Data>>> vertices = new TreeMap<Data, Pair<HashSet<Data>>>();
        
        /**
         * The actual function to create the graph, defined by all associations
         * recorded so far.
         * 
         * Return: th Graph objects odefined by the associations.
         */
        @SuppressWarnings("synthetic-access")//
        public Graph<Data> build() {
            // Phase I: Determine vertex set, and record mappings.
            for (final Pair<Data> edge : edges) {
                final Data from = edge.first;
                final Data to = edge.second;
                vertices.get(from).second.add(to);
                vertices.get(to).first.add(from);
            }
            // Phase II: create vertex array.
            final Graph.Vertex<Data>[] vs = newVertexArray(vertices.size());
            {
                int i = 0;
                for (final Data d : vertices.keySet()) {
                    final Graph.Vertex<Data>[] from = newVertexArray(vertices.get(d).first.size());
                    final Graph.Vertex<Data>[] to = newVertexArray(vertices.get(d).second.size());
                    vs[i] = new Graph.Vertex<Data>(from, to, d, i);
                    record(d, vs[i]);
                    i++;
                }
            }
            // Phase III: fill vertex array.
            for (final Data d : vertices.keySet()) {
                final Graph.Vertex<Data> v = find(d);
                fill(v.from, vertices.get(d).first);
                fill(v.to, vertices.get(d).second);
            }
            // Phase IV: create and fill edges array
            final Graph.Edge<Data>[] es = newEdgeArray(edges.size());
            {
                int i = 0;
                for (final Pair<Data> p : edges)
                    es[i++] = new Graph.Edge<Data>(find(p.first), find(p.second));
            }
            Arrays.sort(es);
            ensure(es.length == edges.size());
            return new Graph<Data>(vs, es);
        }
        
        private void fill(final Graph.Vertex<Data> a[], final Collection<Data> ds) {
            require(a.length == ds.size());
            int i = 0;
            for (final Data d : ds)
                a[i++] = find(d);
            Arrays.sort(a);
        }
        
        @SuppressWarnings("unchecked")//
        private Graph.Vertex<Data>[] newVertexArray(final int n) {
            return new Graph.Vertex[n];
        }
        
        @SuppressWarnings("unchecked")//
        private Graph.Edge<Data>[] newEdgeArray(final int n) {
            return new Graph.Edge[n];
        }
        
        private Pair<HashSet<Data>> emptyPair() {
            return new Pair<HashSet<Data>>(emptySet(), emptySet());
        }
        
        private HashSet<Data> emptySet() {
            return new HashSet<Data>();
        }
        
        private final HashMap<Data, Graph.Vertex<Data>> data2vertex = new HashMap<Data, Graph.Vertex<Data>>();
        
        private void record(final Data d, final Graph.Vertex<Data> v) {
            data2vertex.put(d, v);
        }
        
        private Graph.Vertex<Data> find(final Data d) {
            return data2vertex.get(d);
        }
        
        private static class Pair<Data> {
            Data first;
            Data second;
            
            public Pair(final Data first, final Data second) {
                nonnull(first);
                nonnull(second);
                this.first = first;
                this.second = second;
            }
            
            @Override public int hashCode() {
                return first.hashCode() >>> 1 ^ second.hashCode();
            }
            
            @Override public boolean equals(final Object o) {
                nonnull(o);
                require(o instanceof Pair);
                nonnull(first);
                nonnull(second);
                @SuppressWarnings("unchecked") final Pair<Data> other = (Pair<Data>) o;
                nonnull(other.first);
                nonnull(other.second);
                return first.equals(other.first) && second.equals(other.second);
            }
        }
    }
}| Metric | Value | Acronym | Explanation | 
|---|---|---|---|
| LOC | 343 | Lines Of Code | Total number of lines in the code | 
| SCC | 118 | SemiColons Count | Total number of semicolon tokens found in the code. | 
| NOT | 1764 | Number Of Tokens | Comments, whitespace and text which cannot be made into a token not included. | 
| VCC | 7417 | Visible Characters Count | The total number of non-white (i.e., not space, tab, newline, carriage return, form feed) characters. | 
| CCC | 5085 | Code Characters Count | Total number of non-white characters in tokens. White space characters in string and character literals are not counted. | 
| UIC | 87 | Unique Identifiers Count | The number of different identifiers found in the code | 
| WHC | 7 | Weighted Horizontal Complexity | A heuritistic on horizontal complexity | 
| Statitic | Value | 
|---|---|
| Average token length | 2.9 | 
| Tokens/line | 5.1 | 
| Visible characters/line | 22 | 
| Code characters/line | 15 | 
| Semicolons/tokens | 6% | 
| Comment text percentage | 31% | 
| Token Kind | Occurrences | 
|---|---|
| KEYWORD | 195 | 
| OPERATOR | 187 | 
| LITERAL | 18 | 
| ID | 633 | 
| PUNCTUATION | 731 | 
| COMMENT | 28 | 
| OTHER | 682 |