backport GossipDeviceStore changes back to trivial.
Change-Id: Ic21835d65f1902769f3ab51d3c9c6174c4e3a16b
Showing
1 changed file
with
53 additions
and
44 deletions
... | @@ -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 | */ | ... | ... |
-
Please register or login to post a comment