All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.usc.citius.hipster.graph.HashBasedHipsterGraph Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
/*
 * Copyright 2014 CITIUS , University of Santiago de Compostela.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package es.usc.citius.hipster.graph;


import es.usc.citius.hipster.util.F;
import es.usc.citius.hipster.util.Function;

import java.util.*;

/**
 * Lightweight implementation of an in-memory, mutable graph backed to a {@link HashMap} where
 * keys are vertices and edges are {@link GraphEdge}s
 */
public class HashBasedHipsterGraph implements HipsterMutableGraph {
    protected HashMap>> connected;

    public HashBasedHipsterGraph(){
        this.connected = new HashMap>>();
    }

    @Override
    public boolean add(V v){
        //add a new entry to the hash map if it does not exist
        if(!connected.containsKey(v)){
            connected.put(v, new LinkedHashSet>());
            return true;
        }
        return false;
    }

    @Override
    public Set add(V... vertices) {
        Set added = new HashSet();
        for(V v : vertices){
            if (add(v)) added.add(v);
        }
        return added;
    }

    @Override
    public boolean remove(V v){
        // Remove all edges related to v
        Set> edges = this.connected.get(v);
        if (edges == null) return false;

        for(Iterator> it = edges.iterator(); it.hasNext(); ){
            // Remove the edge in the list of the selected vertex
            GraphEdge edge = it.next();
            it.remove();

            V v2 = edge.getVertex1().equals(v) ? edge.getVertex2() : edge.getVertex1();
            for(Iterator> it2 = this.connected.get(v2).iterator(); it2.hasNext();){
                GraphEdge edge2 = it2.next();
                if (edge2.getVertex1().equals(v) || edge2.getVertex2().equals(v)){
                    it2.remove();
                }
            }
        }
        this.connected.remove(v);
        return true;
    }

    @Override
    public Set remove(V... vertices) {
        Set removed = new HashSet();
        for(V v : vertices){
            if (remove(v)) removed.add(v);
        }
        return removed;
    }

    @Override
    public GraphEdge connect(V v1, V v2, E value){
        // Check non-null arguments
        if(v1 == null || v2 == null) throw new IllegalArgumentException("Invalid vertices. A vertex cannot be null");
        // Ensure that the vertices are in the graph
        if (!connected.containsKey(v1)) throw new IllegalArgumentException(v1 + " is not a vertex of the graph");
        if (!connected.containsKey(v2)) throw new IllegalArgumentException(v2 + " is not a vertex of the graph");
        GraphEdge edge = buildEdge(v1, v2, value);
        // Associate the vertices with their edge
        connected.get(v1).add(edge);
        connected.get(v2).add(edge);
        return edge;
    }

    public GraphEdge buildEdge(V v1, V v2, E value){
        return new UndirectedEdge(v1, v2, value);
    }

    private Map.Entry> createEntry(final V vertex, final GraphEdge edge){
        return new Map.Entry>() {
            @Override
            public V getKey() {
                return vertex;
            }

            @Override
            public GraphEdge getValue() {
                return edge;
            }

            @Override
            public GraphEdge setValue(GraphEdge value) {
                throw new UnsupportedOperationException();
            }
        };
    }

    protected Iterable>> vedges(){
        // TODO: [java-8-migration]
        return F.flatMap(connected.entrySet(), new Function>>, Iterable>>>() {
            @Override
            public Iterable>> apply(final Map.Entry>> entry) {
                return F.map(entry.getValue(), new Function, Map.Entry>>() {
                    @Override
                    public Map.Entry> apply(GraphEdge input) {
                        return createEntry(entry.getKey(), input);
                    }
                });
            }
        });
    }
    /**
     * Returns a list of the edges in the graph.
     * @return edges of the graph.
     */
    @Override
    public Iterable> edges() {
        return F.map(vedges(), new Function>, GraphEdge>() {
            @Override
            public GraphEdge apply(Map.Entry> entry) {
                return entry.getValue();
            }
        });
    }

    /**
     * Returns the vertices of the graph. Any changes in the
     * returned iterator affect the underlying graph structure.
     * @return iterator with the vertices of the graph
     */
    @Override
    public Iterable vertices() {
        return connected.keySet();
    }

    @Override
    public Iterable> edgesOf(V vertex) {
        Set> set = connected.get(vertex);
        if (set == null) set = Collections.emptySet();
        return set;
    }

    /**
     * Returns the internal HashMap representation of the graph
     * @return HashMap where keys are vertices and values a set with the connected edges
     */
    public HashMap>> getConnected() {
        return connected;
    }

    public void setConnected(HashMap>> connected) {
        this.connected = connected;
    }

    public static  HashBasedHipsterGraph create() {
        return new HashBasedHipsterGraph();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy