Thomas Vachuska

Merge remote-tracking branch 'origin/master'

Showing 18 changed files with 104 additions and 123 deletions
1 -/**
2 - * Common abstractions and facilities for implementing distributed store
3 - * using gossip protocol.
4 - */
5 -package org.onlab.onos.store.common.impl;
...@@ -15,7 +15,7 @@ import org.onlab.onos.net.device.DefaultPortDescription; ...@@ -15,7 +15,7 @@ import org.onlab.onos.net.device.DefaultPortDescription;
15 import org.onlab.onos.net.device.DeviceDescription; 15 import org.onlab.onos.net.device.DeviceDescription;
16 import org.onlab.onos.net.device.PortDescription; 16 import org.onlab.onos.net.device.PortDescription;
17 import org.onlab.onos.store.Timestamp; 17 import org.onlab.onos.store.Timestamp;
18 -import org.onlab.onos.store.common.impl.Timestamped; 18 +import org.onlab.onos.store.impl.Timestamped;
19 19
20 /* 20 /*
21 * Collection of Description of a Device and Ports, given from a Provider. 21 * Collection of Description of a Device and Ports, given from a Provider.
......
...@@ -38,7 +38,7 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; ...@@ -38,7 +38,7 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
38 import org.onlab.onos.store.cluster.messaging.ClusterMessage; 38 import org.onlab.onos.store.cluster.messaging.ClusterMessage;
39 import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; 39 import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler;
40 import org.onlab.onos.store.cluster.messaging.MessageSubject; 40 import org.onlab.onos.store.cluster.messaging.MessageSubject;
41 -import org.onlab.onos.store.common.impl.Timestamped; 41 +import org.onlab.onos.store.impl.Timestamped;
42 import org.onlab.onos.store.serializers.KryoSerializer; 42 import org.onlab.onos.store.serializers.KryoSerializer;
43 import org.onlab.onos.store.serializers.DistributedStoreSerializers; 43 import org.onlab.onos.store.serializers.DistributedStoreSerializers;
44 import org.onlab.util.KryoPool; 44 import org.onlab.util.KryoPool;
......
1 -package org.onlab.onos.store.device.impl;
2 -
3 -import static com.google.common.base.Preconditions.checkNotNull;
4 -
5 -import org.apache.commons.lang3.concurrent.ConcurrentException;
6 -import org.apache.commons.lang3.concurrent.ConcurrentInitializer;
7 -import org.onlab.onos.net.device.DeviceDescription;
8 -import org.onlab.onos.store.common.impl.Timestamped;
9 -
10 -// FIXME: consider removing this class
11 -public final class InitDeviceDescs
12 - implements ConcurrentInitializer<DeviceDescriptions> {
13 -
14 - private final Timestamped<DeviceDescription> deviceDesc;
15 -
16 - public InitDeviceDescs(Timestamped<DeviceDescription> deviceDesc) {
17 - this.deviceDesc = checkNotNull(deviceDesc);
18 - }
19 - @Override
20 - public DeviceDescriptions get() throws ConcurrentException {
21 - return new DeviceDescriptions(deviceDesc);
22 - }
23 -}
...@@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; ...@@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl;
3 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
4 import org.onlab.onos.net.device.DeviceDescription; 4 import org.onlab.onos.net.device.DeviceDescription;
5 import org.onlab.onos.net.provider.ProviderId; 5 import org.onlab.onos.net.provider.ProviderId;
6 -import org.onlab.onos.store.common.impl.Timestamped; 6 +import org.onlab.onos.store.impl.Timestamped;
7 7
8 import com.google.common.base.MoreObjects; 8 import com.google.common.base.MoreObjects;
9 9
......
...@@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; ...@@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl;
3 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
4 import org.onlab.onos.net.device.DeviceDescription; 4 import org.onlab.onos.net.device.DeviceDescription;
5 import org.onlab.onos.net.provider.ProviderId; 5 import org.onlab.onos.net.provider.ProviderId;
6 -import org.onlab.onos.store.common.impl.Timestamped; 6 +import org.onlab.onos.store.impl.Timestamped;
7 7
8 import com.esotericsoftware.kryo.Kryo; 8 import com.esotericsoftware.kryo.Kryo;
9 import com.esotericsoftware.kryo.Serializer; 9 import com.esotericsoftware.kryo.Serializer;
......
...@@ -5,7 +5,7 @@ import java.util.List; ...@@ -5,7 +5,7 @@ import java.util.List;
5 import org.onlab.onos.net.DeviceId; 5 import org.onlab.onos.net.DeviceId;
6 import org.onlab.onos.net.device.PortDescription; 6 import org.onlab.onos.net.device.PortDescription;
7 import org.onlab.onos.net.provider.ProviderId; 7 import org.onlab.onos.net.provider.ProviderId;
8 -import org.onlab.onos.store.common.impl.Timestamped; 8 +import org.onlab.onos.store.impl.Timestamped;
9 9
10 import com.google.common.base.MoreObjects; 10 import com.google.common.base.MoreObjects;
11 11
......
...@@ -5,7 +5,7 @@ import java.util.List; ...@@ -5,7 +5,7 @@ import java.util.List;
5 import org.onlab.onos.net.DeviceId; 5 import org.onlab.onos.net.DeviceId;
6 import org.onlab.onos.net.device.PortDescription; 6 import org.onlab.onos.net.device.PortDescription;
7 import org.onlab.onos.net.provider.ProviderId; 7 import org.onlab.onos.net.provider.ProviderId;
8 -import org.onlab.onos.store.common.impl.Timestamped; 8 +import org.onlab.onos.store.impl.Timestamped;
9 9
10 import com.esotericsoftware.kryo.Kryo; 10 import com.esotericsoftware.kryo.Kryo;
11 import com.esotericsoftware.kryo.Serializer; 11 import com.esotericsoftware.kryo.Serializer;
......
...@@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; ...@@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl;
3 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
4 import org.onlab.onos.net.device.PortDescription; 4 import org.onlab.onos.net.device.PortDescription;
5 import org.onlab.onos.net.provider.ProviderId; 5 import org.onlab.onos.net.provider.ProviderId;
6 -import org.onlab.onos.store.common.impl.Timestamped; 6 +import org.onlab.onos.store.impl.Timestamped;
7 7
8 import com.google.common.base.MoreObjects; 8 import com.google.common.base.MoreObjects;
9 9
......
...@@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; ...@@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl;
3 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
4 import org.onlab.onos.net.device.PortDescription; 4 import org.onlab.onos.net.device.PortDescription;
5 import org.onlab.onos.net.provider.ProviderId; 5 import org.onlab.onos.net.provider.ProviderId;
6 -import org.onlab.onos.store.common.impl.Timestamped; 6 +import org.onlab.onos.store.impl.Timestamped;
7 7
8 import com.esotericsoftware.kryo.Kryo; 8 import com.esotericsoftware.kryo.Kryo;
9 import com.esotericsoftware.kryo.Serializer; 9 import com.esotericsoftware.kryo.Serializer;
......
...@@ -38,7 +38,7 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; ...@@ -38,7 +38,7 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
38 import org.onlab.onos.store.cluster.messaging.ClusterMessage; 38 import org.onlab.onos.store.cluster.messaging.ClusterMessage;
39 import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; 39 import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler;
40 import org.onlab.onos.store.cluster.messaging.MessageSubject; 40 import org.onlab.onos.store.cluster.messaging.MessageSubject;
41 -import org.onlab.onos.store.common.impl.Timestamped; 41 +import org.onlab.onos.store.impl.Timestamped;
42 import org.onlab.onos.store.serializers.DistributedStoreSerializers; 42 import org.onlab.onos.store.serializers.DistributedStoreSerializers;
43 import org.onlab.onos.store.serializers.KryoSerializer; 43 import org.onlab.onos.store.serializers.KryoSerializer;
44 import org.onlab.packet.IpPrefix; 44 import org.onlab.packet.IpPrefix;
......
1 -package org.onlab.onos.store.common.impl; 1 +package org.onlab.onos.store.impl;
2 2
3 import static com.google.common.base.Preconditions.checkNotNull; 3 import static com.google.common.base.Preconditions.checkNotNull;
4 4
...@@ -58,12 +58,12 @@ public final class Timestamped<T> { ...@@ -58,12 +58,12 @@ public final class Timestamped<T> {
58 } 58 }
59 59
60 /** 60 /**
61 - * Tests if this timestamp is newer thatn the specified timestamp. 61 + * Tests if this timestamp is newer than the specified timestamp.
62 - * @param timestamp to compare agains 62 + * @param other timestamp to compare against
63 * @return true if this instance is newer 63 * @return true if this instance is newer
64 */ 64 */
65 - public boolean isNewer(Timestamp timestamp) { 65 + public boolean isNewer(Timestamp other) {
66 - return this.timestamp.compareTo(checkNotNull(timestamp)) > 0; 66 + return this.timestamp.compareTo(checkNotNull(other)) > 0;
67 } 67 }
68 68
69 @Override 69 @Override
......
...@@ -39,7 +39,7 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; ...@@ -39,7 +39,7 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
39 import org.onlab.onos.store.cluster.messaging.ClusterMessage; 39 import org.onlab.onos.store.cluster.messaging.ClusterMessage;
40 import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; 40 import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler;
41 import org.onlab.onos.store.cluster.messaging.MessageSubject; 41 import org.onlab.onos.store.cluster.messaging.MessageSubject;
42 -import org.onlab.onos.store.common.impl.Timestamped; 42 +import org.onlab.onos.store.impl.Timestamped;
43 import org.onlab.onos.store.serializers.DistributedStoreSerializers; 43 import org.onlab.onos.store.serializers.DistributedStoreSerializers;
44 import org.onlab.onos.store.serializers.KryoSerializer; 44 import org.onlab.onos.store.serializers.KryoSerializer;
45 import org.onlab.util.KryoPool; 45 import org.onlab.util.KryoPool;
......
...@@ -4,7 +4,7 @@ import com.google.common.base.MoreObjects; ...@@ -4,7 +4,7 @@ import com.google.common.base.MoreObjects;
4 4
5 import org.onlab.onos.net.link.LinkDescription; 5 import org.onlab.onos.net.link.LinkDescription;
6 import org.onlab.onos.net.provider.ProviderId; 6 import org.onlab.onos.net.provider.ProviderId;
7 -import org.onlab.onos.store.common.impl.Timestamped; 7 +import org.onlab.onos.store.impl.Timestamped;
8 8
9 /** 9 /**
10 * Information published by GossipDeviceStore to notify peers of a device 10 * Information published by GossipDeviceStore to notify peers of a device
......
1 package org.onlab.onos.store.serializers; 1 package org.onlab.onos.store.serializers;
2 2
3 -import org.onlab.onos.store.common.impl.Timestamped;
4 import org.onlab.onos.store.impl.MastershipBasedTimestamp; 3 import org.onlab.onos.store.impl.MastershipBasedTimestamp;
4 +import org.onlab.onos.store.impl.Timestamped;
5 import org.onlab.onos.store.impl.WallClockTimestamp; 5 import org.onlab.onos.store.impl.WallClockTimestamp;
6 import org.onlab.util.KryoPool; 6 import org.onlab.util.KryoPool;
7 7
......
1 -package org.onlab.onos.store.common.impl; 1 +package org.onlab.onos.store.impl;
2 2
3 import static org.junit.Assert.*; 3 import static org.junit.Assert.*;
4 4
...@@ -6,7 +6,6 @@ import java.nio.ByteBuffer; ...@@ -6,7 +6,6 @@ import java.nio.ByteBuffer;
6 6
7 import org.junit.Test; 7 import org.junit.Test;
8 import org.onlab.onos.store.Timestamp; 8 import org.onlab.onos.store.Timestamp;
9 -import org.onlab.onos.store.impl.MastershipBasedTimestamp;
10 import org.onlab.util.KryoPool; 9 import org.onlab.util.KryoPool;
11 10
12 import com.google.common.testing.EqualsTester; 11 import com.google.common.testing.EqualsTester;
......
...@@ -5,8 +5,6 @@ import com.google.common.collect.ImmutableList; ...@@ -5,8 +5,6 @@ import com.google.common.collect.ImmutableList;
5 import com.google.common.collect.Maps; 5 import com.google.common.collect.Maps;
6 import com.google.common.collect.Sets; 6 import com.google.common.collect.Sets;
7 7
8 -import org.apache.commons.lang3.concurrent.ConcurrentException;
9 -import org.apache.commons.lang3.concurrent.ConcurrentInitializer;
10 import org.apache.felix.scr.annotations.Activate; 8 import org.apache.felix.scr.annotations.Activate;
11 import org.apache.felix.scr.annotations.Component; 9 import org.apache.felix.scr.annotations.Component;
12 import org.apache.felix.scr.annotations.Deactivate; 10 import org.apache.felix.scr.annotations.Deactivate;
...@@ -35,6 +33,7 @@ import org.slf4j.Logger; ...@@ -35,6 +33,7 @@ import org.slf4j.Logger;
35 33
36 import java.util.ArrayList; 34 import java.util.ArrayList;
37 import java.util.Collections; 35 import java.util.Collections;
36 +import java.util.HashMap;
38 import java.util.HashSet; 37 import java.util.HashSet;
39 import java.util.Iterator; 38 import java.util.Iterator;
40 import java.util.List; 39 import java.util.List;
...@@ -71,8 +70,7 @@ public class SimpleDeviceStore ...@@ -71,8 +70,7 @@ public class SimpleDeviceStore
71 public static final String DEVICE_NOT_FOUND = "Device with ID %s not found"; 70 public static final String DEVICE_NOT_FOUND = "Device with ID %s not found";
72 71
73 // collection of Description given from various providers 72 // collection of Description given from various providers
74 - private final ConcurrentMap<DeviceId, 73 + private final ConcurrentMap<DeviceId, Map<ProviderId, DeviceDescriptions>>
75 - ConcurrentMap<ProviderId, DeviceDescriptions>>
76 deviceDescs = Maps.newConcurrentMap(); 74 deviceDescs = Maps.newConcurrentMap();
77 75
78 // cache of Device and Ports generated by compositing descriptions from providers 76 // cache of Device and Ports generated by compositing descriptions from providers
...@@ -117,15 +115,16 @@ public class SimpleDeviceStore ...@@ -117,15 +115,16 @@ public class SimpleDeviceStore
117 DeviceId deviceId, 115 DeviceId deviceId,
118 DeviceDescription deviceDescription) { 116 DeviceDescription deviceDescription) {
119 117
120 - ConcurrentMap<ProviderId, DeviceDescriptions> providerDescs 118 + Map<ProviderId, DeviceDescriptions> providerDescs
121 - = getDeviceDescriptions(deviceId); 119 + = getOrCreateDeviceDescriptions(deviceId);
122 120
123 synchronized (providerDescs) { 121 synchronized (providerDescs) {
124 // locking per device 122 // locking per device
125 123
126 DeviceDescriptions descs 124 DeviceDescriptions descs
127 - = createIfAbsentUnchecked(providerDescs, providerId, 125 + = getOrCreateProviderDeviceDescriptions(providerDescs,
128 - new InitDeviceDescs(deviceDescription)); 126 + providerId,
127 + deviceDescription);
129 128
130 Device oldDevice = devices.get(deviceId); 129 Device oldDevice = devices.get(deviceId);
131 // update description 130 // update description
...@@ -192,8 +191,8 @@ public class SimpleDeviceStore ...@@ -192,8 +191,8 @@ public class SimpleDeviceStore
192 191
193 @Override 192 @Override
194 public DeviceEvent markOffline(DeviceId deviceId) { 193 public DeviceEvent markOffline(DeviceId deviceId) {
195 - ConcurrentMap<ProviderId, DeviceDescriptions> providerDescs 194 + Map<ProviderId, DeviceDescriptions> providerDescs
196 - = getDeviceDescriptions(deviceId); 195 + = getOrCreateDeviceDescriptions(deviceId);
197 196
198 // locking device 197 // locking device
199 synchronized (providerDescs) { 198 synchronized (providerDescs) {
...@@ -218,7 +217,7 @@ public class SimpleDeviceStore ...@@ -218,7 +217,7 @@ public class SimpleDeviceStore
218 Device device = devices.get(deviceId); 217 Device device = devices.get(deviceId);
219 checkArgument(device != null, DEVICE_NOT_FOUND, deviceId); 218 checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
220 219
221 - ConcurrentMap<ProviderId, DeviceDescriptions> descsMap = deviceDescs.get(deviceId); 220 + Map<ProviderId, DeviceDescriptions> descsMap = deviceDescs.get(deviceId);
222 checkArgument(descsMap != null, DEVICE_NOT_FOUND, deviceId); 221 checkArgument(descsMap != null, DEVICE_NOT_FOUND, deviceId);
223 222
224 List<DeviceEvent> events = new ArrayList<>(); 223 List<DeviceEvent> events = new ArrayList<>();
...@@ -287,12 +286,12 @@ public class SimpleDeviceStore ...@@ -287,12 +286,12 @@ public class SimpleDeviceStore
287 Map<PortNumber, Port> ports, 286 Map<PortNumber, Port> ports,
288 Set<PortNumber> processed) { 287 Set<PortNumber> processed) {
289 List<DeviceEvent> events = new ArrayList<>(); 288 List<DeviceEvent> events = new ArrayList<>();
290 - Iterator<PortNumber> iterator = ports.keySet().iterator(); 289 + Iterator<Entry<PortNumber, Port>> iterator = ports.entrySet().iterator();
291 while (iterator.hasNext()) { 290 while (iterator.hasNext()) {
292 - PortNumber portNumber = iterator.next(); 291 + Entry<PortNumber, Port> e = iterator.next();
292 + PortNumber portNumber = e.getKey();
293 if (!processed.contains(portNumber)) { 293 if (!processed.contains(portNumber)) {
294 - events.add(new DeviceEvent(PORT_REMOVED, device, 294 + events.add(new DeviceEvent(PORT_REMOVED, device, e.getValue()));
295 - ports.get(portNumber)));
296 iterator.remove(); 295 iterator.remove();
297 } 296 }
298 } 297 }
...@@ -306,10 +305,36 @@ public class SimpleDeviceStore ...@@ -306,10 +305,36 @@ public class SimpleDeviceStore
306 NewConcurrentHashMap.<PortNumber, Port>ifNeeded()); 305 NewConcurrentHashMap.<PortNumber, Port>ifNeeded());
307 } 306 }
308 307
309 - private ConcurrentMap<ProviderId, DeviceDescriptions> getDeviceDescriptions( 308 + private Map<ProviderId, DeviceDescriptions> getOrCreateDeviceDescriptions(
310 DeviceId deviceId) { 309 DeviceId deviceId) {
311 - return createIfAbsentUnchecked(deviceDescs, deviceId, 310 + Map<ProviderId, DeviceDescriptions> r;
312 - NewConcurrentHashMap.<ProviderId, DeviceDescriptions>ifNeeded()); 311 + r = deviceDescs.get(deviceId);
312 + if (r != null) {
313 + return r;
314 + }
315 + r = new HashMap<>();
316 + final Map<ProviderId, DeviceDescriptions> concurrentlyAdded;
317 + concurrentlyAdded = deviceDescs.putIfAbsent(deviceId, r);
318 + if (concurrentlyAdded != null) {
319 + return concurrentlyAdded;
320 + } else {
321 + return r;
322 + }
323 + }
324 +
325 + // Guarded by deviceDescs value (=Device lock)
326 + private DeviceDescriptions getOrCreateProviderDeviceDescriptions(
327 + Map<ProviderId, DeviceDescriptions> device,
328 + ProviderId providerId, DeviceDescription deltaDesc) {
329 +
330 + synchronized (device) {
331 + DeviceDescriptions r = device.get(providerId);
332 + if (r == null) {
333 + r = new DeviceDescriptions(deltaDesc);
334 + device.put(providerId, r);
335 + }
336 + return r;
337 + }
313 } 338 }
314 339
315 @Override 340 @Override
...@@ -318,12 +343,12 @@ public class SimpleDeviceStore ...@@ -318,12 +343,12 @@ public class SimpleDeviceStore
318 Device device = devices.get(deviceId); 343 Device device = devices.get(deviceId);
319 checkArgument(device != null, DEVICE_NOT_FOUND, deviceId); 344 checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
320 345
321 - ConcurrentMap<ProviderId, DeviceDescriptions> descsMap = deviceDescs.get(deviceId); 346 + Map<ProviderId, DeviceDescriptions> descsMap = deviceDescs.get(deviceId);
322 checkArgument(descsMap != null, DEVICE_NOT_FOUND, deviceId); 347 checkArgument(descsMap != null, DEVICE_NOT_FOUND, deviceId);
323 348
324 synchronized (descsMap) { 349 synchronized (descsMap) {
325 DeviceDescriptions descs = descsMap.get(providerId); 350 DeviceDescriptions descs = descsMap.get(providerId);
326 - // assuming all providers must to give DeviceDescription 351 + // assuming all providers must give DeviceDescription first
327 checkArgument(descs != null, 352 checkArgument(descs != null,
328 "Device description for Device ID %s from Provider %s was not found", 353 "Device description for Device ID %s from Provider %s was not found",
329 deviceId, providerId); 354 deviceId, providerId);
...@@ -367,7 +392,7 @@ public class SimpleDeviceStore ...@@ -367,7 +392,7 @@ public class SimpleDeviceStore
367 392
368 @Override 393 @Override
369 public DeviceEvent removeDevice(DeviceId deviceId) { 394 public DeviceEvent removeDevice(DeviceId deviceId) {
370 - ConcurrentMap<ProviderId, DeviceDescriptions> descs = getDeviceDescriptions(deviceId); 395 + Map<ProviderId, DeviceDescriptions> descs = getOrCreateDeviceDescriptions(deviceId);
371 synchronized (descs) { 396 synchronized (descs) {
372 Device device = devices.remove(deviceId); 397 Device device = devices.remove(deviceId);
373 // should DEVICE_REMOVED carry removed ports? 398 // should DEVICE_REMOVED carry removed ports?
...@@ -390,7 +415,7 @@ public class SimpleDeviceStore ...@@ -390,7 +415,7 @@ public class SimpleDeviceStore
390 * @return Device instance 415 * @return Device instance
391 */ 416 */
392 private Device composeDevice(DeviceId deviceId, 417 private Device composeDevice(DeviceId deviceId,
393 - ConcurrentMap<ProviderId, DeviceDescriptions> providerDescs) { 418 + Map<ProviderId, DeviceDescriptions> providerDescs) {
394 419
395 checkArgument(!providerDescs.isEmpty(), "No Device descriptions supplied"); 420 checkArgument(!providerDescs.isEmpty(), "No Device descriptions supplied");
396 421
...@@ -429,14 +454,14 @@ public class SimpleDeviceStore ...@@ -429,14 +454,14 @@ public class SimpleDeviceStore
429 * 454 *
430 * @param device device the port is on 455 * @param device device the port is on
431 * @param number port number 456 * @param number port number
432 - * @param providerDescs Collection of Descriptions from multiple providers 457 + * @param descsMap Collection of Descriptions from multiple providers
433 * @return Port instance 458 * @return Port instance
434 */ 459 */
435 private Port composePort(Device device, PortNumber number, 460 private Port composePort(Device device, PortNumber number,
436 - ConcurrentMap<ProviderId, DeviceDescriptions> providerDescs) { 461 + Map<ProviderId, DeviceDescriptions> descsMap) {
437 462
438 - ProviderId primary = pickPrimaryPID(providerDescs); 463 + ProviderId primary = pickPrimaryPID(descsMap);
439 - DeviceDescriptions primDescs = providerDescs.get(primary); 464 + DeviceDescriptions primDescs = descsMap.get(primary);
440 // if no primary, assume not enabled 465 // if no primary, assume not enabled
441 // TODO: revisit this default port enabled/disabled behavior 466 // TODO: revisit this default port enabled/disabled behavior
442 boolean isEnabled = false; 467 boolean isEnabled = false;
...@@ -448,7 +473,7 @@ public class SimpleDeviceStore ...@@ -448,7 +473,7 @@ public class SimpleDeviceStore
448 annotations = merge(annotations, portDesc.annotations()); 473 annotations = merge(annotations, portDesc.annotations());
449 } 474 }
450 475
451 - for (Entry<ProviderId, DeviceDescriptions> e : providerDescs.entrySet()) { 476 + for (Entry<ProviderId, DeviceDescriptions> e : descsMap.entrySet()) {
452 if (e.getKey().equals(primary)) { 477 if (e.getKey().equals(primary)) {
453 continue; 478 continue;
454 } 479 }
...@@ -470,10 +495,9 @@ public class SimpleDeviceStore ...@@ -470,10 +495,9 @@ public class SimpleDeviceStore
470 /** 495 /**
471 * @return primary ProviderID, or randomly chosen one if none exists 496 * @return primary ProviderID, or randomly chosen one if none exists
472 */ 497 */
473 - private ProviderId pickPrimaryPID( 498 + private ProviderId pickPrimaryPID(Map<ProviderId, DeviceDescriptions> descsMap) {
474 - ConcurrentMap<ProviderId, DeviceDescriptions> providerDescs) {
475 ProviderId fallBackPrimary = null; 499 ProviderId fallBackPrimary = null;
476 - for (Entry<ProviderId, DeviceDescriptions> e : providerDescs.entrySet()) { 500 + for (Entry<ProviderId, DeviceDescriptions> e : descsMap.entrySet()) {
477 if (!e.getKey().isAncillary()) { 501 if (!e.getKey().isAncillary()) {
478 return e.getKey(); 502 return e.getKey();
479 } else if (fallBackPrimary == null) { 503 } else if (fallBackPrimary == null) {
...@@ -484,21 +508,6 @@ public class SimpleDeviceStore ...@@ -484,21 +508,6 @@ public class SimpleDeviceStore
484 return fallBackPrimary; 508 return fallBackPrimary;
485 } 509 }
486 510
487 - public static final class InitDeviceDescs
488 - implements ConcurrentInitializer<DeviceDescriptions> {
489 -
490 - private final DeviceDescription deviceDesc;
491 -
492 - public InitDeviceDescs(DeviceDescription deviceDesc) {
493 - this.deviceDesc = checkNotNull(deviceDesc);
494 - }
495 - @Override
496 - public DeviceDescriptions get() throws ConcurrentException {
497 - return new DeviceDescriptions(deviceDesc);
498 - }
499 - }
500 -
501 -
502 /** 511 /**
503 * Collection of Description of a Device and it's Ports given from a Provider. 512 * Collection of Description of a Device and it's Ports given from a Provider.
504 */ 513 */
......
1 package org.onlab.onos.store.trivial.impl; 1 package org.onlab.onos.store.trivial.impl;
2 2
3 import com.google.common.base.Function; 3 import com.google.common.base.Function;
4 -import com.google.common.base.Predicate;
5 import com.google.common.collect.FluentIterable; 4 import com.google.common.collect.FluentIterable;
6 import com.google.common.collect.HashMultimap; 5 import com.google.common.collect.HashMultimap;
7 import com.google.common.collect.SetMultimap; 6 import com.google.common.collect.SetMultimap;
8 7
9 -import org.apache.commons.lang3.concurrent.ConcurrentUtils;
10 import org.apache.felix.scr.annotations.Activate; 8 import org.apache.felix.scr.annotations.Activate;
11 import org.apache.felix.scr.annotations.Component; 9 import org.apache.felix.scr.annotations.Component;
12 import org.apache.felix.scr.annotations.Deactivate; 10 import org.apache.felix.scr.annotations.Deactivate;
...@@ -20,7 +18,6 @@ import org.onlab.onos.net.Link; ...@@ -20,7 +18,6 @@ import org.onlab.onos.net.Link;
20 import org.onlab.onos.net.SparseAnnotations; 18 import org.onlab.onos.net.SparseAnnotations;
21 import org.onlab.onos.net.Link.Type; 19 import org.onlab.onos.net.Link.Type;
22 import org.onlab.onos.net.LinkKey; 20 import org.onlab.onos.net.LinkKey;
23 -import org.onlab.onos.net.Provided;
24 import org.onlab.onos.net.link.DefaultLinkDescription; 21 import org.onlab.onos.net.link.DefaultLinkDescription;
25 import org.onlab.onos.net.link.LinkDescription; 22 import org.onlab.onos.net.link.LinkDescription;
26 import org.onlab.onos.net.link.LinkEvent; 23 import org.onlab.onos.net.link.LinkEvent;
...@@ -28,11 +25,12 @@ import org.onlab.onos.net.link.LinkStore; ...@@ -28,11 +25,12 @@ import org.onlab.onos.net.link.LinkStore;
28 import org.onlab.onos.net.link.LinkStoreDelegate; 25 import org.onlab.onos.net.link.LinkStoreDelegate;
29 import org.onlab.onos.net.provider.ProviderId; 26 import org.onlab.onos.net.provider.ProviderId;
30 import org.onlab.onos.store.AbstractStore; 27 import org.onlab.onos.store.AbstractStore;
31 -import org.onlab.util.NewConcurrentHashMap;
32 import org.slf4j.Logger; 28 import org.slf4j.Logger;
33 29
34 import java.util.Collections; 30 import java.util.Collections;
31 +import java.util.HashMap;
35 import java.util.HashSet; 32 import java.util.HashSet;
33 +import java.util.Map;
36 import java.util.Set; 34 import java.util.Set;
37 import java.util.Map.Entry; 35 import java.util.Map.Entry;
38 import java.util.concurrent.ConcurrentHashMap; 36 import java.util.concurrent.ConcurrentHashMap;
...@@ -47,6 +45,7 @@ import static org.onlab.onos.net.link.LinkEvent.Type.*; ...@@ -47,6 +45,7 @@ import static org.onlab.onos.net.link.LinkEvent.Type.*;
47 import static org.slf4j.LoggerFactory.getLogger; 45 import static org.slf4j.LoggerFactory.getLogger;
48 import static com.google.common.collect.Multimaps.synchronizedSetMultimap; 46 import static com.google.common.collect.Multimaps.synchronizedSetMultimap;
49 import static com.google.common.base.Predicates.notNull; 47 import static com.google.common.base.Predicates.notNull;
48 +import static com.google.common.base.Verify.verifyNotNull;
50 49
51 /** 50 /**
52 * Manages inventory of infrastructure links using trivial in-memory structures 51 * Manages inventory of infrastructure links using trivial in-memory structures
...@@ -61,8 +60,7 @@ public class SimpleLinkStore ...@@ -61,8 +60,7 @@ public class SimpleLinkStore
61 private final Logger log = getLogger(getClass()); 60 private final Logger log = getLogger(getClass());
62 61
63 // Link inventory 62 // Link inventory
64 - private final ConcurrentMap<LinkKey, 63 + private final ConcurrentMap<LinkKey, Map<ProviderId, LinkDescription>>
65 - ConcurrentMap<ProviderId, LinkDescription>>
66 linkDescs = new ConcurrentHashMap<>(); 64 linkDescs = new ConcurrentHashMap<>();
67 65
68 // Link instance cache 66 // Link instance cache
...@@ -151,7 +149,7 @@ public class SimpleLinkStore ...@@ -151,7 +149,7 @@ public class SimpleLinkStore
151 LinkDescription linkDescription) { 149 LinkDescription linkDescription) {
152 LinkKey key = linkKey(linkDescription.src(), linkDescription.dst()); 150 LinkKey key = linkKey(linkDescription.src(), linkDescription.dst());
153 151
154 - ConcurrentMap<ProviderId, LinkDescription> descs = getLinkDescriptions(key); 152 + Map<ProviderId, LinkDescription> descs = getOrCreateLinkDescriptions(key);
155 synchronized (descs) { 153 synchronized (descs) {
156 final Link oldLink = links.get(key); 154 final Link oldLink = links.get(key);
157 // update description 155 // update description
...@@ -166,7 +164,7 @@ public class SimpleLinkStore ...@@ -166,7 +164,7 @@ public class SimpleLinkStore
166 164
167 // Guarded by linkDescs value (=locking each Link) 165 // Guarded by linkDescs value (=locking each Link)
168 private LinkDescription createOrUpdateLinkDescription( 166 private LinkDescription createOrUpdateLinkDescription(
169 - ConcurrentMap<ProviderId, LinkDescription> descs, 167 + Map<ProviderId, LinkDescription> descs,
170 ProviderId providerId, 168 ProviderId providerId,
171 LinkDescription linkDescription) { 169 LinkDescription linkDescription) {
172 170
...@@ -227,7 +225,7 @@ public class SimpleLinkStore ...@@ -227,7 +225,7 @@ public class SimpleLinkStore
227 @Override 225 @Override
228 public LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) { 226 public LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) {
229 final LinkKey key = linkKey(src, dst); 227 final LinkKey key = linkKey(src, dst);
230 - ConcurrentMap<ProviderId, LinkDescription> descs = getLinkDescriptions(key); 228 + Map<ProviderId, LinkDescription> descs = getOrCreateLinkDescriptions(key);
231 synchronized (descs) { 229 synchronized (descs) {
232 Link link = links.remove(key); 230 Link link = links.remove(key);
233 descs.clear(); 231 descs.clear();
...@@ -247,8 +245,8 @@ public class SimpleLinkStore ...@@ -247,8 +245,8 @@ public class SimpleLinkStore
247 /** 245 /**
248 * @return primary ProviderID, or randomly chosen one if none exists 246 * @return primary ProviderID, or randomly chosen one if none exists
249 */ 247 */
250 - private ProviderId pickPrimaryPID( 248 + // Guarded by linkDescs value (=locking each Link)
251 - ConcurrentMap<ProviderId, LinkDescription> providerDescs) { 249 + private ProviderId getBaseProviderId(Map<ProviderId, LinkDescription> providerDescs) {
252 250
253 ProviderId fallBackPrimary = null; 251 ProviderId fallBackPrimary = null;
254 for (Entry<ProviderId, LinkDescription> e : providerDescs.entrySet()) { 252 for (Entry<ProviderId, LinkDescription> e : providerDescs.entrySet()) {
...@@ -262,9 +260,10 @@ public class SimpleLinkStore ...@@ -262,9 +260,10 @@ public class SimpleLinkStore
262 return fallBackPrimary; 260 return fallBackPrimary;
263 } 261 }
264 262
265 - private Link composeLink(ConcurrentMap<ProviderId, LinkDescription> descs) { 263 + // Guarded by linkDescs value (=locking each Link)
266 - ProviderId primary = pickPrimaryPID(descs); 264 + private Link composeLink(Map<ProviderId, LinkDescription> descs) {
267 - LinkDescription base = descs.get(primary); 265 + ProviderId primary = getBaseProviderId(descs);
266 + LinkDescription base = descs.get(verifyNotNull(primary));
268 267
269 ConnectPoint src = base.src(); 268 ConnectPoint src = base.src();
270 ConnectPoint dst = base.dst(); 269 ConnectPoint dst = base.dst();
...@@ -289,9 +288,20 @@ public class SimpleLinkStore ...@@ -289,9 +288,20 @@ public class SimpleLinkStore
289 return new DefaultLink(primary , src, dst, type, annotations); 288 return new DefaultLink(primary , src, dst, type, annotations);
290 } 289 }
291 290
292 - private ConcurrentMap<ProviderId, LinkDescription> getLinkDescriptions(LinkKey key) { 291 + private Map<ProviderId, LinkDescription> getOrCreateLinkDescriptions(LinkKey key) {
293 - return ConcurrentUtils.createIfAbsentUnchecked(linkDescs, key, 292 + Map<ProviderId, LinkDescription> r;
294 - NewConcurrentHashMap.<ProviderId, LinkDescription>ifNeeded()); 293 + r = linkDescs.get(key);
294 + if (r != null) {
295 + return r;
296 + }
297 + r = new HashMap<>();
298 + final Map<ProviderId, LinkDescription> concurrentlyAdded;
299 + concurrentlyAdded = linkDescs.putIfAbsent(key, r);
300 + if (concurrentlyAdded == null) {
301 + return r;
302 + } else {
303 + return concurrentlyAdded;
304 + }
295 } 305 }
296 306
297 private final Function<LinkKey, Link> lookupLink = new LookupLink(); 307 private final Function<LinkKey, Link> lookupLink = new LookupLink();
...@@ -302,20 +312,11 @@ public class SimpleLinkStore ...@@ -302,20 +312,11 @@ public class SimpleLinkStore
302 private final class LookupLink implements Function<LinkKey, Link> { 312 private final class LookupLink implements Function<LinkKey, Link> {
303 @Override 313 @Override
304 public Link apply(LinkKey input) { 314 public Link apply(LinkKey input) {
305 - return links.get(input); 315 + if (input == null) {
306 - } 316 + return null;
307 - } 317 + } else {
308 - 318 + return links.get(input);
309 - private static final Predicate<Provided> IS_PRIMARY = new IsPrimary(); 319 + }
310 - private static final Predicate<Provided> isPrimary() {
311 - return IS_PRIMARY;
312 - }
313 -
314 - private static final class IsPrimary implements Predicate<Provided> {
315 -
316 - @Override
317 - public boolean apply(Provided input) {
318 - return !input.providerId().isAncillary();
319 } 320 }
320 } 321 }
321 } 322 }
......