Committed by
Yuta Higuchi
Workaround for ConcurrentModificationException
- Workaround fix for ONOS-1193 - If locking the whole link collection damages the performance, apply the fix suggested on GossipLinkStore comment. Change-Id: Idd4d2e5b8e3a50843fe7abd10a615cfbd9a16478 (cherry picked from commit 4d973eba)
Showing
2 changed files
with
19 additions
and
0 deletions
| ... | @@ -238,6 +238,18 @@ public class GossipLinkStore | ... | @@ -238,6 +238,18 @@ public class GossipLinkStore |
| 238 | @Override | 238 | @Override |
| 239 | public Set<Link> getEgressLinks(ConnectPoint src) { | 239 | public Set<Link> getEgressLinks(ConnectPoint src) { |
| 240 | Set<Link> egress = new HashSet<>(); | 240 | Set<Link> egress = new HashSet<>(); |
| 241 | + // | ||
| 242 | + // Change `srcLinks` to ConcurrentMap<DeviceId, (Concurrent)Set> | ||
| 243 | + // to remove this synchronized block, if we hit performance issue. | ||
| 244 | + // SetMultiMap#get returns wrapped collection to provide modifiable-view. | ||
| 245 | + // And the wrapped collection is not concurrent access safe. | ||
| 246 | + // | ||
| 247 | + // Our use case here does not require returned collection to be modifiable, | ||
| 248 | + // so the wrapped collection forces us to lock the whole multiset, | ||
| 249 | + // for benefit we don't need. | ||
| 250 | + // | ||
| 251 | + // Same applies to `dstLinks` | ||
| 252 | + synchronized (srcLinks) { | ||
| 241 | for (LinkKey linkKey : srcLinks.get(src.deviceId())) { | 253 | for (LinkKey linkKey : srcLinks.get(src.deviceId())) { |
| 242 | if (linkKey.src().equals(src)) { | 254 | if (linkKey.src().equals(src)) { |
| 243 | Link link = links.get(linkKey); | 255 | Link link = links.get(linkKey); |
| ... | @@ -248,12 +260,14 @@ public class GossipLinkStore | ... | @@ -248,12 +260,14 @@ public class GossipLinkStore |
| 248 | } | 260 | } |
| 249 | } | 261 | } |
| 250 | } | 262 | } |
| 263 | + } | ||
| 251 | return egress; | 264 | return egress; |
| 252 | } | 265 | } |
| 253 | 266 | ||
| 254 | @Override | 267 | @Override |
| 255 | public Set<Link> getIngressLinks(ConnectPoint dst) { | 268 | public Set<Link> getIngressLinks(ConnectPoint dst) { |
| 256 | Set<Link> ingress = new HashSet<>(); | 269 | Set<Link> ingress = new HashSet<>(); |
| 270 | + synchronized (dstLinks) { | ||
| 257 | for (LinkKey linkKey : dstLinks.get(dst.deviceId())) { | 271 | for (LinkKey linkKey : dstLinks.get(dst.deviceId())) { |
| 258 | if (linkKey.dst().equals(dst)) { | 272 | if (linkKey.dst().equals(dst)) { |
| 259 | Link link = links.get(linkKey); | 273 | Link link = links.get(linkKey); |
| ... | @@ -264,6 +278,7 @@ public class GossipLinkStore | ... | @@ -264,6 +278,7 @@ public class GossipLinkStore |
| 264 | } | 278 | } |
| 265 | } | 279 | } |
| 266 | } | 280 | } |
| 281 | + } | ||
| 267 | return ingress; | 282 | return ingress; |
| 268 | } | 283 | } |
| 269 | 284 | ... | ... |
| ... | @@ -146,22 +146,26 @@ public class SimpleLinkStore | ... | @@ -146,22 +146,26 @@ public class SimpleLinkStore |
| 146 | @Override | 146 | @Override |
| 147 | public Set<Link> getEgressLinks(ConnectPoint src) { | 147 | public Set<Link> getEgressLinks(ConnectPoint src) { |
| 148 | Set<Link> egress = new HashSet<>(); | 148 | Set<Link> egress = new HashSet<>(); |
| 149 | + synchronized (srcLinks) { | ||
| 149 | for (LinkKey linkKey : srcLinks.get(src.deviceId())) { | 150 | for (LinkKey linkKey : srcLinks.get(src.deviceId())) { |
| 150 | if (linkKey.src().equals(src)) { | 151 | if (linkKey.src().equals(src)) { |
| 151 | egress.add(links.get(linkKey)); | 152 | egress.add(links.get(linkKey)); |
| 152 | } | 153 | } |
| 153 | } | 154 | } |
| 155 | + } | ||
| 154 | return egress; | 156 | return egress; |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 157 | @Override | 159 | @Override |
| 158 | public Set<Link> getIngressLinks(ConnectPoint dst) { | 160 | public Set<Link> getIngressLinks(ConnectPoint dst) { |
| 159 | Set<Link> ingress = new HashSet<>(); | 161 | Set<Link> ingress = new HashSet<>(); |
| 162 | + synchronized (dstLinks) { | ||
| 160 | for (LinkKey linkKey : dstLinks.get(dst.deviceId())) { | 163 | for (LinkKey linkKey : dstLinks.get(dst.deviceId())) { |
| 161 | if (linkKey.dst().equals(dst)) { | 164 | if (linkKey.dst().equals(dst)) { |
| 162 | ingress.add(links.get(linkKey)); | 165 | ingress.add(links.get(linkKey)); |
| 163 | } | 166 | } |
| 164 | } | 167 | } |
| 168 | + } | ||
| 165 | return ingress; | 169 | return ingress; |
| 166 | } | 170 | } |
| 167 | 171 | ... | ... |
-
Please register or login to post a comment