blob: 9efd9119fe48a05fc25337e90cb11d40d6c1a61d [file] [log] [blame]
Jonathan Hart472062d2014-04-03 10:56:48 -07001package net.onrc.onos.core.topology;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -08002
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -07003import static com.google.common.base.Preconditions.checkNotNull;
4
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -07005import java.util.ArrayList;
Yuta HIGUCHIfa742842014-07-03 22:35:13 -07006import java.util.Collection;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -08007import java.util.Collections;
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -07008import java.util.HashMap;
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -07009import java.util.Iterator;
Pavlin Radoslavov054cd592014-08-07 20:57:16 -070010import java.util.LinkedList;
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -070011import java.util.List;
12import java.util.Map;
Sangho Shin2f263692014-09-15 14:09:41 -070013import java.util.Map.Entry;
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070014import java.util.SortedSet;
15import java.util.TreeSet;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080016import java.util.concurrent.ConcurrentHashMap;
17import java.util.concurrent.ConcurrentMap;
Jonathan Hart26f291b2014-02-18 16:57:24 -080018import java.util.concurrent.locks.Lock;
19import java.util.concurrent.locks.ReadWriteLock;
20import java.util.concurrent.locks.ReentrantReadWriteLock;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080021
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -070022import javax.annotation.concurrent.GuardedBy;
23
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070024import net.floodlightcontroller.core.IFloodlightProviderService.Role;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080025import net.floodlightcontroller.util.MACAddress;
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -070026import net.onrc.onos.core.util.Dpid;
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -070027import net.onrc.onos.core.util.LinkTuple;
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070028import net.onrc.onos.core.util.OnosInstanceId;
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -070029import net.onrc.onos.core.util.PortNumber;
Jonathan Hart25bd53e2014-04-30 23:44:09 -070030import net.onrc.onos.core.util.SwitchPort;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080031
32import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
Yuta HIGUCHIfa742842014-07-03 22:35:13 -070035import com.google.common.collect.HashMultimap;
36import com.google.common.collect.Multimap;
37import com.google.common.collect.Multimaps;
38
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -070039
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070040// TODO add TopologyManager, etc. to populate Mastership information.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -070041/**
42 * Class to represent an instance of Topology Snapshot.
43 */
Yuta HIGUCHI9e6223d2014-08-26 00:01:32 -070044public class TopologyImpl implements MutableTopology, MutableInternalTopology {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -070045
Jonathan Harte37e4e22014-05-13 19:12:02 -070046 private static final Logger log = LoggerFactory.getLogger(TopologyImpl.class);
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080047
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -070048 // TODO Revisit Map types after implementing CoW/lock-free
49
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070050 // Mastership info
51 // Dpid -> [ (InstanceID, Role) ]
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -070052 private final Map<Dpid, SortedSet<MastershipData>> mastership;
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070053
Ray Milkey269ffb92014-04-03 14:43:30 -070054 // DPID -> Switch
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -070055 private final ConcurrentMap<Dpid, SwitchData> switches;
56 private final ConcurrentMap<Dpid, ConcurrentMap<PortNumber, PortData>> ports;
Yuta HIGUCHIfa742842014-07-03 22:35:13 -070057
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -070058 // Index from Port to Host
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -070059 private final Multimap<SwitchPort, HostData> hosts;
60 private final ConcurrentMap<MACAddress, HostData> mac2Host;
Jonathan Hart25bd53e2014-04-30 23:44:09 -070061
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -070062 // SwitchPort -> (type -> Link)
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -070063 private final ConcurrentMap<SwitchPort, ConcurrentMap<String, LinkData>> outgoingLinks;
64 private final ConcurrentMap<SwitchPort, ConcurrentMap<String, LinkData>> incomingLinks;
Yuta HIGUCHI5d2d8d42014-02-20 22:22:53 -080065
Yuta HIGUCHI9e6223d2014-08-26 00:01:32 -070066 private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
67 private final Lock readLock = readWriteLock.readLock();
Ray Milkey269ffb92014-04-03 14:43:30 -070068 // TODO use the write lock after refactor
Yuta HIGUCHI9e6223d2014-08-26 00:01:32 -070069 private final Lock writeLock = readWriteLock.writeLock();
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080070
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -070071 /**
72 * Create an empty Topology.
73 */
Jonathan Harte37e4e22014-05-13 19:12:02 -070074 public TopologyImpl() {
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070075 mastership = new HashMap<>();
Ray Milkey269ffb92014-04-03 14:43:30 -070076 // TODO: Does these object need to be stored in Concurrent Collection?
77 switches = new ConcurrentHashMap<>();
Yuta HIGUCHIfa742842014-07-03 22:35:13 -070078 ports = new ConcurrentHashMap<>();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -070079 hosts = Multimaps.synchronizedMultimap(
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -070080 HashMultimap.<SwitchPort, HostData>create());
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -070081 mac2Host = new ConcurrentHashMap<>();
Jonathan Hart25bd53e2014-04-30 23:44:09 -070082 outgoingLinks = new ConcurrentHashMap<>();
83 incomingLinks = new ConcurrentHashMap<>();
Ray Milkey269ffb92014-04-03 14:43:30 -070084 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080085
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -070086 /**
87 * Create a shallow copy of given Topology.
88 *
89 * @param original Topology
90 */
91 public TopologyImpl(TopologyImpl original) {
92 original.acquireReadLock();
93 try {
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070094 // shallow copy Set in Map
95 this.mastership = new HashMap<>(original.mastership.size());
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -070096 for (Entry<Dpid, SortedSet<MastershipData>> e
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -070097 : original.mastership.entrySet()) {
98 this.mastership.put(e.getKey(), new TreeSet<>(e.getValue()));
99 }
100
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700101 this.switches = new ConcurrentHashMap<>(original.switches);
102
103 // shallow copy Map in Map
104 this.ports = new ConcurrentHashMap<>(original.ports.size());
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700105 for (Entry<Dpid, ConcurrentMap<PortNumber, PortData>> entry
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700106 : original.ports.entrySet()) {
107 this.ports.put(entry.getKey(), new ConcurrentHashMap<>(entry.getValue()));
108 }
109
110 this.hosts = Multimaps.synchronizedMultimap(
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700111 HashMultimap.<SwitchPort, HostData>create(original.hosts));
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700112 this.mac2Host = new ConcurrentHashMap<>(original.mac2Host);
113
114 // shallow copy Map in Map
115 this.outgoingLinks = new ConcurrentHashMap<>(original.outgoingLinks.size());
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700116 for (Entry<SwitchPort, ConcurrentMap<String, LinkData>> entry
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700117 : original.outgoingLinks.entrySet()) {
118 this.outgoingLinks.put(entry.getKey(), new ConcurrentHashMap<>(entry.getValue()));
119 }
120
121 // shallow copy Map in Map
122 this.incomingLinks = new ConcurrentHashMap<>(original.incomingLinks.size());
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700123 for (Entry<SwitchPort, ConcurrentMap<String, LinkData>> entry
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700124 : original.incomingLinks.entrySet()) {
125 this.incomingLinks.put(entry.getKey(), new ConcurrentHashMap<>(entry.getValue()));
126 }
127 } finally {
128 original.releaseReadLock();
129 }
130 }
131
Ray Milkey269ffb92014-04-03 14:43:30 -0700132 @Override
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700133 public Switch getSwitch(Dpid dpid) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700134 final SwitchData sw = switches.get(dpid);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700135 if (sw != null) {
136 return new SwitchImpl(this, dpid);
137 } else {
138 return null;
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700139 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700140 }
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800141
Ray Milkey269ffb92014-04-03 14:43:30 -0700142 @Override
143 public Iterable<Switch> getSwitches() {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700144 List<Switch> list = new ArrayList<>(switches.size());
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700145 for (SwitchData elm : switches.values()) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700146 list.add(new SwitchImpl(this, elm.getDpid()));
147 }
148 return list;
Ray Milkey269ffb92014-04-03 14:43:30 -0700149 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800150
Ray Milkey269ffb92014-04-03 14:43:30 -0700151 @Override
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700152 public Port getPort(Dpid dpid, PortNumber number) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700153 ConcurrentMap<PortNumber, PortData> portMap = ports.get(dpid);
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700154 if (portMap != null) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700155 final PortData port = portMap.get(number);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700156 if (port != null) {
157 return new PortImpl(this, port.getSwitchPort());
158 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700159 }
160 return null;
161 }
Pavlin Radoslavov06df22a2014-02-18 19:16:27 -0800162
Ray Milkey269ffb92014-04-03 14:43:30 -0700163 @Override
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700164 public Port getPort(SwitchPort port) {
Pavlin Radoslavov3d322f42014-08-18 14:58:55 -0700165 return getPort(port.getDpid(), port.getPortNumber());
Jonathan Hart25bd53e2014-04-30 23:44:09 -0700166 }
167
168 @Override
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700169 public Collection<Port> getPorts(Dpid dpid) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700170 ConcurrentMap<PortNumber, PortData> portMap = ports.get(dpid);
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700171 if (portMap == null) {
172 return Collections.emptyList();
173 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700174 List<Port> list = new ArrayList<>(portMap.size());
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700175 for (PortData elm : portMap.values()) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700176 list.add(new PortImpl(this, elm.getSwitchPort()));
177 }
178 return list;
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700179 }
180
181 @Override
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700182 public Link getOutgoingLink(Dpid dpid, PortNumber number) {
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700183 return getOutgoingLink(new SwitchPort(dpid, number));
Ray Milkey269ffb92014-04-03 14:43:30 -0700184 }
Pavlin Radoslavov7c8f69a2014-02-19 19:01:45 -0800185
Ray Milkey269ffb92014-04-03 14:43:30 -0700186 @Override
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700187 public Link getOutgoingLink(SwitchPort port) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700188 Map<String, LinkData> links = outgoingLinks.get(port);
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700189 return getPacketLinkIfExists(links);
190 }
191
192 // TODO remove when we no longer need packet fall back behavior
193 /**
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700194 * Gets the "packet" link if such exists,
195 * if not return whichever link is found first.
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700196 *
197 * @param links Collection of links to search from
198 * @return Link instance found or null if no link exists
199 */
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700200 private Link getPacketLinkIfExists(Map<String, LinkData> links) {
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700201
202 if (links == null) {
203 return null;
204 }
205
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700206 LinkData link = links.get(TopologyElement.TYPE_PACKET_LAYER);
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700207 if (link != null) {
208 // return packet link
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700209 return new LinkImpl(this, link.getLinkTuple());
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700210 } else {
211 // return whatever found
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700212 Iterator<LinkData> it = links.values().iterator();
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700213 if (it.hasNext()) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700214 return new LinkImpl(this, it.next().getLinkTuple());
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700215 }
216 }
217 return null;
218 }
219
220 @Override
221 public Link getOutgoingLink(Dpid dpid, PortNumber number, String type) {
222 return getOutgoingLink(new SwitchPort(dpid, number), type);
223 }
224
225 @Override
226 public Link getOutgoingLink(SwitchPort port, String type) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700227 Map<String, LinkData> links = outgoingLinks.get(port);
228 final LinkData link = links.get(type);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700229 if (link != null) {
230 return new LinkImpl(this, link.getLinkTuple());
231 }
232 return null;
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700233 }
234
235 @Override
236 public Collection<Link> getOutgoingLinks(SwitchPort port) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700237 ConcurrentMap<String, LinkData> typeMap = outgoingLinks.get(port);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700238 if (typeMap == null) {
239 return Collections.emptyList();
240 }
241 return toLinkImpls(typeMap.values());
242 }
243
244 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700245 * Converts collection of LinkData to collection of LinkImpls.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700246 *
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700247 * @param links collection of LinkData
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700248 * @return collection of LinkImpls
249 */
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700250 private Collection<Link> toLinkImpls(final Collection<LinkData> links) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700251 if (links == null) {
252 return Collections.emptyList();
253 }
254 List<Link> list = new ArrayList<>(links.size());
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700255 for (LinkData elm : links) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700256 list.add(new LinkImpl(this, elm.getLinkTuple()));
257 }
258 return list;
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700259 }
260
261 @Override
262 public Link getIncomingLink(Dpid dpid, PortNumber number) {
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700263 return getIncomingLink(new SwitchPort(dpid, number));
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700264 }
265
266 @Override
267 public Link getIncomingLink(SwitchPort port) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700268 Map<String, LinkData> links = incomingLinks.get(port);
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700269 return getPacketLinkIfExists(links);
270 }
271
272 @Override
273 public Link getIncomingLink(Dpid dpid, PortNumber number, String type) {
274 return getIncomingLink(new SwitchPort(dpid, number), type);
275 }
276
277 @Override
278 public Link getIncomingLink(SwitchPort port, String type) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700279 Map<String, LinkData> links = incomingLinks.get(port);
280 final LinkData link = links.get(type);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700281 if (link != null) {
282 return new LinkImpl(this, link.getLinkTuple());
283 }
284 return null;
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700285 }
286
287 @Override
288 public Collection<Link> getIncomingLinks(SwitchPort port) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700289 ConcurrentMap<String, LinkData> typeMap = incomingLinks.get(port);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700290 if (typeMap == null) {
291 return Collections.emptyList();
292 }
293 return toLinkImpls(typeMap.values());
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700294 }
295
296 @Override
297 public Link getLink(Dpid srcDpid, PortNumber srcNumber,
298 Dpid dstDpid, PortNumber dstNumber) {
299
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700300 final SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstNumber);
301 Collection<Link> links = getOutgoingLinks(new SwitchPort(srcDpid, srcNumber));
302 for (Link link : links) {
303 if (link == null) {
304 continue;
305 }
Yuta HIGUCHIcd14dda2014-07-24 09:57:22 -0700306 if (link.getDstPort().getSwitchPort().equals(dstSwitchPort)) {
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700307 return link;
308 }
309 }
310 return null;
311 }
312
313 @Override
314 public Link getLink(Dpid srcDpid, PortNumber srcNumber,
315 Dpid dstDpid, PortNumber dstNumber,
316 String type) {
317
318 Link link = getOutgoingLink(srcDpid, srcNumber, type);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700319 if (link == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700320 return null;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700321 }
322 if (!link.getDstSwitch().getDpid().equals(dstDpid)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700323 return null;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700324 }
325 if (!link.getDstPort().getNumber().equals(dstNumber)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700326 return null;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700327 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700328 return link;
329 }
Pavlin Radoslavov7c8f69a2014-02-19 19:01:45 -0800330
Ray Milkey269ffb92014-04-03 14:43:30 -0700331 @Override
332 public Iterable<Link> getLinks() {
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700333 List<Link> links = new ArrayList<>();
334
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700335 for (Map<String, LinkData> portLinks : outgoingLinks.values()) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700336 if (portLinks == null) {
337 continue;
338 }
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700339 for (LinkData elm : portLinks.values()) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700340 links.add(new LinkImpl(this, elm.getLinkTuple()));
341 }
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700342 }
343 return links;
Jonathan Hart25bd53e2014-04-30 23:44:09 -0700344 }
Toshio Koide2f570c12014-02-06 16:55:32 -0800345
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700346 @Override
347 public Host getHostByMac(MACAddress address) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700348 HostData host = mac2Host.get(address);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700349 if (host != null) {
350 return new HostImpl(this, address);
351 }
352 return null;
353 }
354
355 @Override
356 public Iterable<Host> getHosts() {
357 return toHostImpls(mac2Host.values());
358 }
359
360 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700361 * Converts collection of HostData to collection of HostImpl.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700362 *
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700363 * @param events collection of HostData
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700364 * @return collection of HostImpl
365 */
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700366 private List<Host> toHostImpls(Collection<HostData> events) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700367 if (events == null) {
368 return Collections.emptyList();
369 }
370 List<Host> list = new ArrayList<>(events.size());
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700371 for (HostData elm : events) {
Sangho Shin2f263692014-09-15 14:09:41 -0700372 list.add(new HostImpl(this, elm.getMac(), elm.getIp()));
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700373 }
374 return list;
375 }
376
377 @Override
378 public Collection<Host> getHosts(SwitchPort port) {
379 return toHostImpls(hosts.get(port));
380 }
381
382 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700383 public SwitchData getSwitchData(final Dpid dpid) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700384 return this.switches.get(dpid);
385 }
386
387 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700388 public Collection<SwitchData> getAllSwitchDataEntries() {
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700389 return Collections.unmodifiableCollection(switches.values());
390 }
391
392 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700393 public PortData getPortData(final SwitchPort port) {
394 return getPortData(port.getDpid(), port.getPortNumber());
Yuta HIGUCHI45ccade2014-08-18 17:09:19 -0700395 }
396
397 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700398 public PortData getPortData(final Dpid dpid, PortNumber portNumber) {
399 ConcurrentMap<PortNumber, PortData> portMap = this.ports.get(dpid);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700400 if (portMap != null) {
Yuta HIGUCHI45ccade2014-08-18 17:09:19 -0700401 return portMap.get(portNumber);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700402 }
403 return null;
404 }
405
406 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700407 public Collection<PortData> getPortDataEntries(final Dpid dpid) {
408 ConcurrentMap<PortNumber, PortData> portList = ports.get(dpid);
Yuta HIGUCHI45ccade2014-08-18 17:09:19 -0700409 if (portList == null) {
410 return Collections.emptyList();
411 }
412 return Collections.unmodifiableCollection(portList.values());
413 }
414
415 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700416 public Collection<PortData> getAllPortDataEntries() {
417 List<PortData> events = new LinkedList<>();
418 for (ConcurrentMap<PortNumber, PortData> cm : ports.values()) {
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700419 events.addAll(cm.values());
420 }
421 return Collections.unmodifiableCollection(events);
422 }
423
424 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700425 public LinkData getLinkData(final LinkTuple linkId) {
426 ConcurrentMap<String, LinkData> links = this.outgoingLinks.get(linkId.getSrc());
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700427 if (links == null) {
428 return null;
429 }
430
431 // TODO Should we look for Packet link first?
432 // Not unless invariant is broken.
433
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700434 for (LinkData link : links.values()) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700435 if (link.getDst().equals(linkId.getDst())) {
436 return link;
437 }
438 }
439 return null;
440 }
441
442 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700443 public LinkData getLinkData(final LinkTuple linkId, final String type) {
444 ConcurrentMap<String, LinkData> links = this.outgoingLinks.get(linkId.getSrc());
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700445 if (links == null) {
446 return null;
447 }
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700448 LinkData link = links.get(type);
Yuta HIGUCHI4f328842014-08-28 17:23:09 -0700449 if (link.getDst().equals(linkId.getDst())) {
450 return link;
451 }
452 return null;
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700453 }
454
455 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700456 public Collection<LinkData> getLinkDataEntriesFrom(SwitchPort srcPort) {
457 ConcurrentMap<String, LinkData> links = this.outgoingLinks.get(srcPort);
Yuta HIGUCHI9e6223d2014-08-26 00:01:32 -0700458 if (links == null) {
459 return Collections.emptyList();
460 }
461 return Collections.unmodifiableCollection(links.values());
462 }
463
464 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700465 public Collection<LinkData> getLinkDataEntriesTo(SwitchPort dstPort) {
466 ConcurrentMap<String, LinkData> links = this.incomingLinks.get(dstPort);
Yuta HIGUCHI9e6223d2014-08-26 00:01:32 -0700467 if (links == null) {
468 return Collections.emptyList();
469 }
470 return Collections.unmodifiableCollection(links.values());
471 }
472
473 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700474 public Collection<LinkData> getLinkDataEntries(final LinkTuple linkId) {
475 ConcurrentMap<String, LinkData> links = this.outgoingLinks.get(linkId.getSrc());
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700476 if (links == null) {
477 return Collections.emptyList();
478 }
479
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700480 List<LinkData> linkDataEntries = new ArrayList<>();
481 for (LinkData e : links.values()) {
Yuta HIGUCHI4f328842014-08-28 17:23:09 -0700482 if (e.getDst().equals(linkId.getDst())) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700483 linkDataEntries.add(e);
Yuta HIGUCHI4f328842014-08-28 17:23:09 -0700484 }
485 }
486
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700487 // unless invariant is broken, this should contain at most 1 element.
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700488 return linkDataEntries;
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700489 }
490
491 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700492 public Collection<LinkData> getAllLinkDataEntries() {
493 List<LinkData> events = new LinkedList<>();
494 for (ConcurrentMap<String, LinkData> cm : outgoingLinks.values()) {
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700495 events.addAll(cm.values());
496 }
497 return Collections.unmodifiableCollection(events);
498 }
499
500 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700501 public HostData getHostData(final MACAddress mac) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700502 return this.mac2Host.get(mac);
503 }
504
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700505 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700506 public Collection<HostData> getHostDataEntries(SwitchPort port) {
Yuta HIGUCHI9e6223d2014-08-26 00:01:32 -0700507 return Collections.unmodifiableCollection(hosts.get(port));
508 }
509
510 @Override
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700511 public Collection<HostData> getAllHostDataEntries() {
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700512 return Collections.unmodifiableCollection(mac2Host.values());
513 }
514
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700515 @Override
516 public OnosInstanceId getSwitchMaster(Dpid dpid) {
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700517 final SortedSet<MastershipData> candidates = mastership.get(dpid);
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700518 if (candidates == null) {
519 return null;
520 }
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700521 for (MastershipData candidate : candidates) {
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700522 if (candidate.getRole() == Role.MASTER) {
523 return candidate.getOnosInstanceId();
524 }
525 }
526 return null;
527 }
528
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700529 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700530 * Puts a SwitchData.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700531 *
532 * @param sw Switch to add. (Will be frozen if not already)
533 */
534 @GuardedBy("writeLock")
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700535 protected void putSwitch(SwitchData sw) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700536 // TODO isFrozen check once we implement CoW/lock-free
537 switches.put(sw.getDpid(), sw.freeze());
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700538 ports.putIfAbsent(sw.getDpid(), new ConcurrentHashMap<PortNumber, PortData>());
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700539 }
540
541 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700542 * Removes a SwitchData from this snapshot.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700543 * <p/>
544 * Will also remove ports, if it has not been removed already.
545 *
546 * @param dpid Switch DPID
547 */
548 @GuardedBy("writeLock")
549 protected void removeSwitch(Dpid dpid) {
550 // TODO isFrozen check once we implement CoW/lock-free
551 switches.remove(dpid);
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700552 ConcurrentMap<PortNumber, PortData> removedPorts = ports.remove(dpid);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700553 if (removedPorts != null && !removedPorts.isEmpty()) {
554 log.warn("Some ports were removed as side-effect of #removeSwitch({})", dpid);
555 }
556 }
557
558 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700559 * Puts a PortData.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700560 *
561 * @param port Port to add. (Will be frozen if not already)
562 */
563 @GuardedBy("writeLock")
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700564 protected void putPort(PortData port) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700565
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700566 ConcurrentMap<PortNumber, PortData> portMap = ports.get(port.getDpid());
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700567 if (portMap == null) {
568 portMap = new ConcurrentHashMap<>();
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700569 ConcurrentMap<PortNumber, PortData> existing
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700570 = ports.putIfAbsent(port.getDpid(), portMap);
571 if (existing != null) {
572 // port map was added concurrently, using theirs
573 portMap = existing;
574 }
575 }
576 portMap.put(port.getPortNumber(), port.freeze());
577 }
578
579 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700580 * Removes a PortData from this snapshot.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700581 *
582 * @param port SwitchPort to remove
583 */
584 @GuardedBy("writeLock")
585 protected void removePort(SwitchPort port) {
586 removePort(port.getDpid(), port.getPortNumber());
587 }
588
589 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700590 * Removes a PortData from this snapshot.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700591 * <p/>
592 * Will also remove ports, if it has not been removed already.
593 *
594 * @param dpid Switch DPID
595 * @param number PortNumber
596 */
597 @GuardedBy("writeLock")
598 protected void removePort(Dpid dpid, PortNumber number) {
599 // TODO sanity check Host attachment point.
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700600 ConcurrentMap<PortNumber, PortData> portMap = ports.get(dpid);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700601 if (portMap != null) {
602 portMap.remove(number);
603 }
604 }
605
606 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700607 * Puts a LinkData.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700608 *
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700609 * @param link LinkData
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700610 */
611 @GuardedBy("writeLock")
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700612 protected void putLink(LinkData link) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700613 // TODO Do sanity check?
614 // - There cannot be 2 links in same direction between a port pair.
615 putLinkMap(outgoingLinks, link.getSrc(), link);
616 putLinkMap(incomingLinks, link.getDst(), link);
Jonathan Hart25bd53e2014-04-30 23:44:09 -0700617 }
618
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700619 /**
620 * Helper method to update outgoingLinks, incomingLinks.
621 *
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700622 * @param linkMap outgoingLinks or incomingLinks to update
623 * @param port {@code linkMap} key to update
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700624 * @param link Link to add
625 */
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700626 @GuardedBy("writeLock")
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700627 private void putLinkMap(ConcurrentMap<SwitchPort, ConcurrentMap<String, LinkData>> linkMap,
628 SwitchPort port, LinkData link) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700629
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700630 ConcurrentMap<String, LinkData> linksOnPort = linkMap.get(port);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700631 if (linksOnPort == null) {
632 linksOnPort = new ConcurrentHashMap<>(4);
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700633 ConcurrentMap<String, LinkData> existing
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700634 = linkMap.putIfAbsent(
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700635 port,
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700636 linksOnPort);
637
638 if (existing != null) {
639 linksOnPort = existing;
640 }
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700641 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700642 linksOnPort.put(link.getType(), link);
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700643 }
644
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700645 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700646 * Removes a LinkData from this snapshot.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700647 *
648 * @param link Link to remove
649 * @param type type of link to remove
650 */
651 @GuardedBy("writeLock")
652 protected void removeLink(LinkTuple link, String type) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700653 ConcurrentMap<String, LinkData> portLinks
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700654 = outgoingLinks.get(link.getSrc());
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700655 if (portLinks != null) {
656 // no conditional update here
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700657 portLinks.remove(type);
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700658 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700659 portLinks
660 = incomingLinks.get(link.getDst());
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700661 if (portLinks != null) {
662 // no conditional update here
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700663 portLinks.remove(type);
Yuta HIGUCHI8313f0b2014-07-09 16:36:03 -0700664 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700665 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800666
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700667 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700668 * Removes a LinkData from this snapshot.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700669 *
670 * @param link Link to remove
671 */
672 @GuardedBy("writeLock")
673 protected void removeLink(LinkTuple link) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700674 Collection<LinkData> links = getLinkDataEntries(link);
675 for (LinkData l : links) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700676 removeLink(link, l.getType());
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700677 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700678 }
679
680 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700681 * Puts a HostData.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700682 * <p/>
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700683 * Removes attachment points for previous HostData and update
684 * them with new HostData
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700685 *
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700686 * @param host HostData
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700687 */
688 @GuardedBy("writeLock")
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700689 protected void putHost(HostData host) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700690 // Host cannot be simply put() to replace instance since it has mobility.
691 // Simply remove -> put for now.
692
693 // remove old attachment points
694 removeHost(host.getMac());
695
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700696 // add new attachment points
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700697 for (SwitchPort port : host.getAttachmentPoints()) {
698 hosts.put(port, host);
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700699 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700700 mac2Host.put(host.getMac(), host);
Ray Milkey269ffb92014-04-03 14:43:30 -0700701 }
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800702
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700703 /**
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700704 * Removes a HostData from this snapshot.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700705 *
706 * @param mac MACAddress of the Host to remove
707 */
708 @GuardedBy("writeLock")
709 protected void removeHost(MACAddress mac) {
Yuta HIGUCHI93d35ea2014-08-31 23:26:13 -0700710 HostData host = mac2Host.remove(mac);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700711 if (host != null) {
712 for (SwitchPort port : host.getAttachmentPoints()) {
713 hosts.remove(port, host);
714 }
Yuta HIGUCHIfa742842014-07-03 22:35:13 -0700715 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700716 }
Jonathan Hart26f291b2014-02-18 16:57:24 -0800717
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700718 /**
719 * Puts a mastership change event.
720 *
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700721 * @param master MastershipData
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700722 */
723 @GuardedBy("writeLock")
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700724 protected void putSwitchMastershipData(MastershipData master) {
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700725 checkNotNull(master);
726
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700727 SortedSet<MastershipData> candidates
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700728 = mastership.get(master.getDpid());
729 if (candidates == null) {
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700730 // SortedSet, customized so that MASTER MastershipData appear
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700731 // earlier during iteration.
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700732 candidates = new TreeSet<>(new MastershipData.MasterFirstComparator());
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700733 }
734
735 // always replace
736 candidates.remove(master);
737 candidates.add(master);
738 }
739
740 /**
741 * Removes a mastership change event.
742 * <p>
743 * Note: Only Dpid and OnosInstanceId will be used to identify the
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700744 * {@link MastershipData} to remove.
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700745 *
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700746 * @param master {@link MastershipData} to remove. (Role is ignored)
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700747 */
748 @GuardedBy("writeLock")
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700749 protected void removeSwitchMastershipData(MastershipData master) {
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700750 checkNotNull(master);
751
Yuta HIGUCHId8fd2f52014-09-01 23:19:45 -0700752 SortedSet<MastershipData> candidates
Yuta HIGUCHIab9dc7b2014-08-26 22:53:13 -0700753 = mastership.get(master.getDpid());
754 if (candidates == null) {
755 // nothing to do
756 return;
757 }
758 candidates.remove(master);
759 }
760
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700761
Ray Milkey269ffb92014-04-03 14:43:30 -0700762 @Override
763 public void acquireReadLock() {
764 readLock.lock();
765 }
Jonathan Hart26f291b2014-02-18 16:57:24 -0800766
Ray Milkey269ffb92014-04-03 14:43:30 -0700767 @Override
768 public void releaseReadLock() {
769 readLock.unlock();
770 }
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800771
Ray Milkey269ffb92014-04-03 14:43:30 -0700772 protected void acquireWriteLock() {
773 writeLock.lock();
774 }
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800775
Ray Milkey269ffb92014-04-03 14:43:30 -0700776 protected void releaseWriteLock() {
777 writeLock.unlock();
778 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800779}