Switch to JDT annotations for Nullable and NonNull
[netvirt.git] / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / AclInterfaceCacheImpl.java
1 /*
2  * Copyright (c) 2017 Inocybe Technologies and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netvirt.aclservice;
9
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.Map.Entry;
13 import java.util.concurrent.ConcurrentHashMap;
14 import java.util.concurrent.ConcurrentMap;
15 import java.util.concurrent.atomic.AtomicBoolean;
16 import java.util.function.BiConsumer;
17 import java.util.function.BiFunction;
18 import javax.inject.Singleton;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
22 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
23 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface.Builder;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Implementation of the AclInterfaceCache interface.
29  *
30  * @author Thomas Pantelis
31  */
32 @Singleton
33 public class AclInterfaceCacheImpl implements AclInterfaceCache {
34     private static final Logger LOG = LoggerFactory.getLogger(AclInterfaceCacheImpl.class);
35
36     private final ConcurrentMap<String, AclInterface> cache = new ConcurrentHashMap<>();
37
38     @Override
39     public AclInterface addOrUpdate(@NonNull String interfaceId,
40             BiConsumer<AclInterface, AclInterface.Builder> updateFunction) {
41         while (true) {
42             // First try to update the existing instance in the cache if one exists.
43             AclInterface aclInterface = cache.computeIfPresent(interfaceId,
44                 (key, prevAclInterface) -> {
45                     Builder builder = AclInterface.builder(prevAclInterface);
46                     updateFunction.accept(prevAclInterface, builder);
47                     return builder.build();
48                 });
49
50             if (aclInterface == null) {
51                 // No existing instance so try to put a new one.
52                 Builder builder = AclInterface.builder();
53                 builder.interfaceId(interfaceId);
54                 updateFunction.accept(null, builder);
55                 aclInterface = builder.build();
56                 if (cache.putIfAbsent(interfaceId, aclInterface) == null) {
57                     // The new instance was added.
58                     return aclInterface;
59                 }
60
61                 // The new instance wasn't added - some one else beat us to it. Loop back up and try again.
62             } else {
63                 return aclInterface;
64             }
65         }
66     }
67
68     @Override
69     public AclInterface updateIfPresent(String interfaceId,
70             BiFunction<AclInterface, AclInterface.Builder, Boolean> updateFunction) {
71         final AtomicBoolean updated = new AtomicBoolean(false);
72         AclInterface aclInterface =  cache.computeIfPresent(interfaceId,
73             (key, prevAclInterface) -> {
74                 Builder builder = AclInterface.builder(prevAclInterface);
75                 updated.set(updateFunction.apply(prevAclInterface, builder));
76                 return builder.build();
77             });
78
79         return updated.get() ? aclInterface : null;
80     }
81
82     @Override
83     @Nullable
84     public AclInterface remove(String interfaceId) {
85         AclInterface aclInterface = cache.get(interfaceId);
86         if (aclInterface == null) {
87             LOG.debug("AclInterface object not found in cache for interface {}", interfaceId);
88             return null;
89         }
90
91         if (aclInterface.isMarkedForDelete()) {
92             cache.remove(interfaceId);
93         } else {
94             aclInterface.setIsMarkedForDelete(true);
95         }
96
97         return aclInterface;
98     }
99
100     @Override
101     public AclInterface get(String interfaceId) {
102         return cache.get(interfaceId);
103     }
104
105     @Override
106     public Collection<Entry<String, AclInterface>> entries() {
107         return new ArrayList<>(cache.entrySet());
108     }
109 }