001/* 002 * Copyright (C) 2016 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.graph; 018 019import static com.google.common.base.Preconditions.checkNotNull; 020 021import com.google.common.annotations.Beta; 022import com.google.common.base.Function; 023import com.google.common.collect.ImmutableCollection; 024import com.google.common.collect.ImmutableMap; 025import com.google.common.collect.Maps; 026import javax.annotation.Nullable; 027 028/** 029 * A {@link ValueGraph} whose elements and structural relationships will never change. Instances of 030 * this class may be obtained with {@link #copyOf(ValueGraph)}. 031 * 032 * <p>This class generally provides all of the same guarantees as {@link ImmutableCollection} 033 * (despite not extending {@link ImmutableCollection} itself), including guaranteed thread-safety. 034 * 035 * @author James Sexton 036 * @param <N> Node parameter type 037 * @param <V> Value parameter type 038 * @since 20.0 039 */ 040@Beta 041public final class ImmutableValueGraph<N, V> extends ImmutableGraph.ValueBackedImpl<N, V> 042 implements ValueGraph<N, V> { 043 044 private ImmutableValueGraph(ValueGraph<N, V> graph) { 045 super(ValueGraphBuilder.from(graph), getNodeConnections(graph), graph.edges().size()); 046 } 047 048 /** Returns an immutable copy of {@code graph}. */ 049 public static <N, V> ImmutableValueGraph<N, V> copyOf(ValueGraph<N, V> graph) { 050 return (graph instanceof ImmutableValueGraph) 051 ? (ImmutableValueGraph<N, V>) graph 052 : new ImmutableValueGraph<N, V>(graph); 053 } 054 055 /** 056 * Simply returns its argument. 057 * 058 * @deprecated no need to use this 059 */ 060 @Deprecated 061 public static <N, V> ImmutableValueGraph<N, V> copyOf(ImmutableValueGraph<N, V> graph) { 062 return checkNotNull(graph); 063 } 064 065 private static <N, V> ImmutableMap<N, GraphConnections<N, V>> getNodeConnections( 066 ValueGraph<N, V> graph) { 067 // ImmutableMap.Builder maintains the order of the elements as inserted, so the map will have 068 // whatever ordering the graph's nodes do, so ImmutableSortedMap is unnecessary even if the 069 // input nodes are sorted. 070 ImmutableMap.Builder<N, GraphConnections<N, V>> nodeConnections = ImmutableMap.builder(); 071 for (N node : graph.nodes()) { 072 nodeConnections.put(node, connectionsOf(graph, node)); 073 } 074 return nodeConnections.build(); 075 } 076 077 private static <N, V> GraphConnections<N, V> connectionsOf( 078 final ValueGraph<N, V> graph, final N node) { 079 Function<N, V> successorNodeToValueFn = 080 new Function<N, V>() { 081 @Override 082 public V apply(N successorNode) { 083 return graph.edgeValue(node, successorNode); 084 } 085 }; 086 return graph.isDirected() 087 ? DirectedGraphConnections.ofImmutable( 088 graph.predecessors(node), Maps.asMap(graph.successors(node), successorNodeToValueFn)) 089 : UndirectedGraphConnections.ofImmutable( 090 Maps.asMap(graph.adjacentNodes(node), successorNodeToValueFn)); 091 } 092 093 @Override 094 public V edgeValue(Object nodeU, Object nodeV) { 095 return backingValueGraph.edgeValue(nodeU, nodeV); 096 } 097 098 @Override 099 public V edgeValueOrDefault(Object nodeU, Object nodeV, @Nullable V defaultValue) { 100 return backingValueGraph.edgeValueOrDefault(nodeU, nodeV, defaultValue); 101 } 102 103 @Override 104 public String toString() { 105 return backingValueGraph.toString(); 106 } 107}