001/* 002 * Copyright 2006 - 2013 003 * Stefan Balev <stefan.balev@graphstream-project.org> 004 * Julien Baudry <julien.baudry@graphstream-project.org> 005 * Antoine Dutot <antoine.dutot@graphstream-project.org> 006 * Yoann Pigné <yoann.pigne@graphstream-project.org> 007 * Guilhelm Savin <guilhelm.savin@graphstream-project.org> 008 * 009 * This file is part of GraphStream <http://graphstream-project.org>. 010 * 011 * GraphStream is a library whose purpose is to handle static or dynamic 012 * graph, create them from scratch, file or any source and display them. 013 * 014 * This program is free software distributed under the terms of two licenses, the 015 * CeCILL-C license that fits European law, and the GNU Lesser General Public 016 * License. You can use, modify and/ or redistribute the software under the terms 017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following 018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by 019 * the Free Software Foundation, either version 3 of the License, or (at your 020 * option) any later version. 021 * 022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 024 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 025 * 026 * You should have received a copy of the GNU Lesser General Public License 027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 028 * 029 * The fact that you are presently reading this means that you have had 030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. 031 */ 032package org.graphstream.graph.implementations; 033 034import java.util.Collection; 035import java.util.Collections; 036import java.util.HashMap; 037import java.util.Iterator; 038import java.util.LinkedList; 039import java.util.List; 040 041import org.graphstream.graph.Edge; 042import org.graphstream.graph.Node; 043 044/** 045 * Nodes used with {@link MultiGraph} 046 * 047 */ 048public class MultiNode extends AdjacencyListNode { 049 protected HashMap<AbstractNode, List<AbstractEdge>> neighborMap; 050 051 // *** Constructor *** 052 053 public MultiNode(AbstractGraph graph, String id) { 054 super(graph, id); 055 neighborMap = new HashMap<AbstractNode, List<AbstractEdge>>( 056 4 * INITIAL_EDGE_CAPACITY / 3 + 1); 057 } 058 059 // *** Helpers *** 060 061 @SuppressWarnings("unchecked") 062 @Override 063 protected <T extends Edge> T locateEdge(Node opposite, char type) { 064 List<AbstractEdge> l = neighborMap.get(opposite); 065 if (l == null) 066 return null; 067 068 for (AbstractEdge e : l) { 069 char etype = edgeType(e); 070 if ((type != I_EDGE || etype != O_EDGE) 071 && (type != O_EDGE || etype != I_EDGE)) 072 return (T) e; 073 } 074 return null; 075 } 076 077 @Override 078 protected void removeEdge(int i) { 079 AbstractNode opposite = edges[i].getOpposite(this); 080 List<AbstractEdge> l = neighborMap.get(opposite); 081 l.remove(edges[i]); 082 if (l.isEmpty()) 083 neighborMap.remove(opposite); 084 super.removeEdge(i); 085 } 086 087 // *** Callbacks *** 088 089 @Override 090 protected boolean addEdgeCallback(AbstractEdge edge) { 091 AbstractNode opposite = edge.getOpposite(this); 092 List<AbstractEdge> l = neighborMap.get(opposite); 093 if (l == null) { 094 l = new LinkedList<AbstractEdge>(); 095 neighborMap.put(opposite, l); 096 } 097 l.add(edge); 098 return super.addEdgeCallback(edge); 099 } 100 101 @Override 102 protected void clearCallback() { 103 neighborMap.clear(); 104 super.clearCallback(); 105 } 106 107 // *** Others *** 108 109 @SuppressWarnings("unchecked") 110 @Override 111 public <T extends Node> Iterator<T> getNeighborNodeIterator() { 112 return (Iterator<T>) Collections.unmodifiableSet(neighborMap.keySet()) 113 .iterator(); 114 } 115 116 @SuppressWarnings("unchecked") 117 public <T extends Edge> Collection<T> getEdgeSetBetween(Node node) { 118 List<AbstractEdge> l = neighborMap.get(node); 119 if (l == null) 120 return Collections.emptyList(); 121 return (Collection<T>) Collections.unmodifiableList(l); 122 } 123 124 public <T extends Edge> Collection<T> getEdgeSetBetween(String id) { 125 return getEdgeSetBetween(graph.getNode(id)); 126 } 127 128 public <T extends Edge> Collection<T> getEdgeSetBetween(int index) { 129 return getEdgeSetBetween(graph.getNode(index)); 130 } 131}