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
Showing
2 changed files
with
19 additions
and
0 deletions
... | @@ -246,6 +246,18 @@ public class GossipLinkStore | ... | @@ -246,6 +246,18 @@ public class GossipLinkStore |
246 | @Override | 246 | @Override |
247 | public Set<Link> getEgressLinks(ConnectPoint src) { | 247 | public Set<Link> getEgressLinks(ConnectPoint src) { |
248 | Set<Link> egress = new HashSet<>(); | 248 | Set<Link> egress = new HashSet<>(); |
249 | + // | ||
250 | + // Change `srcLinks` to ConcurrentMap<DeviceId, (Concurrent)Set> | ||
251 | + // to remove this synchronized block, if we hit performance issue. | ||
252 | + // SetMultiMap#get returns wrapped collection to provide modifiable-view. | ||
253 | + // And the wrapped collection is not concurrent access safe. | ||
254 | + // | ||
255 | + // Our use case here does not require returned collection to be modifiable, | ||
256 | + // so the wrapped collection forces us to lock the whole multiset, | ||
257 | + // for benefit we don't need. | ||
258 | + // | ||
259 | + // Same applies to `dstLinks` | ||
260 | + synchronized (srcLinks) { | ||
249 | for (LinkKey linkKey : srcLinks.get(src.deviceId())) { | 261 | for (LinkKey linkKey : srcLinks.get(src.deviceId())) { |
250 | if (linkKey.src().equals(src)) { | 262 | if (linkKey.src().equals(src)) { |
251 | Link link = links.get(linkKey); | 263 | Link link = links.get(linkKey); |
... | @@ -256,12 +268,14 @@ public class GossipLinkStore | ... | @@ -256,12 +268,14 @@ public class GossipLinkStore |
256 | } | 268 | } |
257 | } | 269 | } |
258 | } | 270 | } |
271 | + } | ||
259 | return egress; | 272 | return egress; |
260 | } | 273 | } |
261 | 274 | ||
262 | @Override | 275 | @Override |
263 | public Set<Link> getIngressLinks(ConnectPoint dst) { | 276 | public Set<Link> getIngressLinks(ConnectPoint dst) { |
264 | Set<Link> ingress = new HashSet<>(); | 277 | Set<Link> ingress = new HashSet<>(); |
278 | + synchronized (dstLinks) { | ||
265 | for (LinkKey linkKey : dstLinks.get(dst.deviceId())) { | 279 | for (LinkKey linkKey : dstLinks.get(dst.deviceId())) { |
266 | if (linkKey.dst().equals(dst)) { | 280 | if (linkKey.dst().equals(dst)) { |
267 | Link link = links.get(linkKey); | 281 | Link link = links.get(linkKey); |
... | @@ -272,6 +286,7 @@ public class GossipLinkStore | ... | @@ -272,6 +286,7 @@ public class GossipLinkStore |
272 | } | 286 | } |
273 | } | 287 | } |
274 | } | 288 | } |
289 | + } | ||
275 | return ingress; | 290 | return ingress; |
276 | } | 291 | } |
277 | 292 | ... | ... |
... | @@ -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