Yuta HIGUCHI

backport GossipDeviceStore changes back to trivial.

Change-Id: Ic21835d65f1902769f3ab51d3c9c6174c4e3a16b
...@@ -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,7 +343,7 @@ public class SimpleDeviceStore ...@@ -318,7 +343,7 @@ 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) {
...@@ -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 */
......