com.salesforce.jgrapht.graph.specifics.UndirectedSpecifics Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of AptSpringProcessor Show documentation
Show all versions of AptSpringProcessor Show documentation
This project contains the apt processor that implements all the checks enumerated in @Verify. It is a self contained, and
shaded jar.
The newest version!
/*
* (C) Copyright 2015-2018, by Barak Naveh and Contributors.
*
* JGraphT : a free Java graph-theory library
*
* See the CONTRIBUTORS.md file distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the
* GNU Lesser General Public License v2.1 or later
* which is available at
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
*
* SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
*/
package com.salesforce.jgrapht.graph.specifics;
import com.salesforce.jgrapht.*;
import com.salesforce.jgrapht.graph.*;
import com.salesforce.jgrapht.util.*;
import java.io.*;
import java.util.*;
import java.util.function.*;
/**
* Plain implementation of UndirectedSpecifics. This implementation requires the least amount of
* memory, at the expense of slow edge retrievals. Methods which depend on edge retrievals, e.g.
* getEdge(V u, V v), containsEdge(V u, V v), addEdge(V u, V v), etc may be relatively slow when the
* average degree of a vertex is high (dense graphs). For a fast implementation, use
* {@link FastLookupUndirectedSpecifics}.
*
* @param the graph vertex type
* @param the graph edge type
*
* @author Barak Naveh
* @author Joris Kinable
*/
public class UndirectedSpecifics
implements
Specifics,
Serializable
{
private static final long serialVersionUID = 4206026440450450992L;
protected Graph graph;
protected Map> vertexMap;
protected EdgeSetFactory edgeSetFactory;
/**
* Construct a new undirected specifics.
*
* @param graph the graph for which these specifics are for
* @param vertexMap map for the storage of vertex edge sets. Needs to have a predictable
* iteration order.
* @param edgeSetFactory factory for the creation of vertex edge sets
*/
public UndirectedSpecifics(
Graph graph, Map> vertexMap,
EdgeSetFactory edgeSetFactory)
{
this.graph = Objects.requireNonNull(graph);
this.vertexMap = Objects.requireNonNull(vertexMap);
this.edgeSetFactory = Objects.requireNonNull(edgeSetFactory);
}
/**
* {@inheritDoc}
*/
@Override
public boolean addVertex(V v)
{
UndirectedEdgeContainer ec = vertexMap.get(v);
if (ec == null) {
vertexMap.put(v, new UndirectedEdgeContainer<>(edgeSetFactory, v));
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public Set getVertexSet()
{
return vertexMap.keySet();
}
/**
* {@inheritDoc}
*/
@Override
public Set getAllEdges(V sourceVertex, V targetVertex)
{
Set edges = null;
if (graph.containsVertex(sourceVertex) && graph.containsVertex(targetVertex)) {
edges = new ArrayUnenforcedSet<>();
for (E e : getEdgeContainer(sourceVertex).vertexEdges) {
boolean equal = isEqualsStraightOrInverted(sourceVertex, targetVertex, e);
if (equal) {
edges.add(e);
}
}
}
return edges;
}
/**
* {@inheritDoc}
*/
@Override
public E getEdge(V sourceVertex, V targetVertex)
{
if (graph.containsVertex(sourceVertex) && graph.containsVertex(targetVertex)) {
for (E e : getEdgeContainer(sourceVertex).vertexEdges) {
boolean equal = isEqualsStraightOrInverted(sourceVertex, targetVertex, e);
if (equal) {
return e;
}
}
}
return null;
}
private boolean isEqualsStraightOrInverted(Object sourceVertex, Object targetVertex, E e)
{
boolean equalStraight = sourceVertex.equals(graph.getEdgeSource(e))
&& targetVertex.equals(graph.getEdgeTarget(e));
boolean equalInverted = sourceVertex.equals(graph.getEdgeTarget(e))
&& targetVertex.equals(graph.getEdgeSource(e));
return equalStraight || equalInverted;
}
@Override
@Deprecated
public void addEdgeToTouchingVertices(E e)
{
V source = graph.getEdgeSource(e);
V target = graph.getEdgeTarget(e);
getEdgeContainer(source).addEdge(e);
if (!source.equals(target)) {
getEdgeContainer(target).addEdge(e);
}
}
@Override
public boolean addEdgeToTouchingVertices(V sourceVertex, V targetVertex, E e)
{
getEdgeContainer(sourceVertex).addEdge(e);
if (!sourceVertex.equals(targetVertex)) {
getEdgeContainer(targetVertex).addEdge(e);
}
return true;
}
@Override
public boolean addEdgeToTouchingVerticesIfAbsent(V sourceVertex, V targetVertex, E e)
{
// lookup for edge with same source and target
UndirectedEdgeContainer ec = getEdgeContainer(sourceVertex);
for (E edge : ec.vertexEdges) {
if (isEqualsStraightOrInverted(sourceVertex, targetVertex, edge)) {
return false;
}
}
// add
ec.addEdge(e);
getEdgeContainer(targetVertex).addEdge(e);
return true;
}
@Override
public E createEdgeToTouchingVerticesIfAbsent(
V sourceVertex, V targetVertex, Supplier edgeSupplier)
{
// lookup for edge with same source and target
UndirectedEdgeContainer ec = getEdgeContainer(sourceVertex);
for (E edge : ec.vertexEdges) {
if (isEqualsStraightOrInverted(sourceVertex, targetVertex, edge)) {
return null;
}
}
// create and add
E e = edgeSupplier.get();
ec.addEdge(e);
getEdgeContainer(targetVertex).addEdge(e);
return e;
}
/**
* {@inheritDoc}
*/
@Override
public int degreeOf(V vertex)
{
if (graph.getType().isAllowingSelfLoops()) {
/*
* Then we must count, and add loops twice
*/
int degree = 0;
Set edges = getEdgeContainer(vertex).vertexEdges;
for (E e : edges) {
if (graph.getEdgeSource(e).equals(graph.getEdgeTarget(e))) {
degree += 2;
} else {
degree += 1;
}
}
return degree;
} else {
return getEdgeContainer(vertex).edgeCount();
}
}
/**
* {@inheritDoc}
*/
@Override
public Set edgesOf(V vertex)
{
return getEdgeContainer(vertex).getUnmodifiableVertexEdges();
}
/**
* {@inheritDoc}
*/
@Override
public int inDegreeOf(V vertex)
{
return degreeOf(vertex);
}
/**
* {@inheritDoc}
*/
@Override
public Set incomingEdgesOf(V vertex)
{
return getEdgeContainer(vertex).getUnmodifiableVertexEdges();
}
/**
* {@inheritDoc}
*/
@Override
public int outDegreeOf(V vertex)
{
return degreeOf(vertex);
}
/**
* {@inheritDoc}
*/
@Override
public Set outgoingEdgesOf(V vertex)
{
return getEdgeContainer(vertex).getUnmodifiableVertexEdges();
}
/**
* {@inheritDoc}
*
* @deprecated Use method {@link #removeEdgeFromTouchingVertices(Object, Object, Object)}
* instead.
*/
@Override
@Deprecated
public void removeEdgeFromTouchingVertices(E e)
{
V source = graph.getEdgeSource(e);
V target = graph.getEdgeTarget(e);
getEdgeContainer(source).removeEdge(e);
if (!source.equals(target)) {
getEdgeContainer(target).removeEdge(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public void removeEdgeFromTouchingVertices(V sourceVertex, V targetVertex, E e)
{
getEdgeContainer(sourceVertex).removeEdge(e);
if (!sourceVertex.equals(targetVertex)) {
getEdgeContainer(targetVertex).removeEdge(e);
}
}
/**
* Get the edge container for a specified vertex.
*
* @param vertex a vertex in this graph
*
* @return an edge container
*/
protected UndirectedEdgeContainer getEdgeContainer(V vertex)
{
UndirectedEdgeContainer ec = vertexMap.get(vertex);
if (ec == null) {
ec = new UndirectedEdgeContainer<>(edgeSetFactory, vertex);
vertexMap.put(vertex, ec);
}
return ec;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy