2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao;
11 import com.google.common.base.Optional;
12 import com.google.common.collect.Iterables;
14 import java.util.concurrent.ConcurrentHashMap;
15 import java.util.concurrent.ConcurrentMap;
16 import java.util.regex.Pattern;
17 import javax.annotation.Nonnull;
18 import javax.annotation.Nullable;
19 import org.apache.commons.net.util.SubnetUtils;
20 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao;
21 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil;
22 import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SubnetInfoKeyDecorator;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet;
27 * Purpose: generic implementation of {@link SimpleCachedDao}
29 public class SimpleCachedDaoEPForwardingTemplateImpl implements SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> {
31 private final ConcurrentMap<IpPrefix, EndpointForwardingTemplateBySubnet> plainCache;
32 private final ConcurrentMap<SubnetInfoKeyDecorator, EndpointForwardingTemplateBySubnet> subnetCache;
33 private final Pattern IP_MASK_EATER_RE = Pattern.compile("/[0-9]+");
35 public SimpleCachedDaoEPForwardingTemplateImpl() {
36 plainCache = new ConcurrentHashMap<>();
37 subnetCache = new ConcurrentHashMap<>();
41 public EndpointForwardingTemplateBySubnet update(@Nonnull final IpPrefix key, @Nullable final EndpointForwardingTemplateBySubnet value) {
42 final EndpointForwardingTemplateBySubnet previousValue;
43 if (EPTemplateUtil.isPlain(key)) {
44 previousValue = updatePlainCache(key, value);
46 previousValue = updateSubnetCache(key, value);
52 private EndpointForwardingTemplateBySubnet updateSubnetCache(final IpPrefix key, final EndpointForwardingTemplateBySubnet value) {
53 final EndpointForwardingTemplateBySubnet previousValue;
54 final SubnetInfoKeyDecorator subnetKey = EPTemplateUtil.buildSubnetInfoKey(key);
56 previousValue = subnetCache.put(subnetKey, value);
58 previousValue = subnetCache.remove(subnetKey);
63 private EndpointForwardingTemplateBySubnet updatePlainCache(final @Nonnull IpPrefix key, final @Nullable EndpointForwardingTemplateBySubnet value) {
64 final EndpointForwardingTemplateBySubnet previousValue;
66 previousValue = plainCache.put(key, value);
68 previousValue = plainCache.remove(key);
74 public Optional<EndpointForwardingTemplateBySubnet> find(@Nonnull final IpPrefix key) {
75 final Optional<EndpointForwardingTemplateBySubnet> template;
76 if (EPTemplateUtil.isPlain(key)) {
77 final Optional<EndpointForwardingTemplateBySubnet> fastPlain = Optional.fromNullable(plainCache.get(key));
78 if (fastPlain.isPresent()) {
81 template = lookupSlowSubnet(key.getIpv4Prefix().getValue());
84 final SubnetInfoKeyDecorator keyDecorator = EPTemplateUtil.buildSubnetInfoKey(key);
85 final Optional<EndpointForwardingTemplateBySubnet> fastSubnet =
86 Optional.fromNullable(subnetCache.get(keyDecorator));
87 if (fastSubnet.isPresent()) {
88 template = fastSubnet;
90 template = Optional.absent();
96 private Optional<EndpointForwardingTemplateBySubnet> lookupSlowSubnet(final String value) {
97 final String plainIp = IP_MASK_EATER_RE.matcher(value).replaceFirst("");
98 EndpointForwardingTemplateBySubnet valueCandidate = null;
100 for (Map.Entry<SubnetInfoKeyDecorator, EndpointForwardingTemplateBySubnet> entry : subnetCache.entrySet()) {
101 final SubnetUtils.SubnetInfo subnetInfo = entry.getKey().getDelegate();
102 if (subnetInfo.isInRange(plainIp)) {
103 final int addressCountTmp = subnetInfo.getAddressCount();
104 if (valueCandidate == null || addressCount > addressCountTmp) {
105 valueCandidate = entry.getValue();
106 addressCount = addressCountTmp;
110 return Optional.fromNullable(valueCandidate);
114 public void invalidateCache() {
120 public boolean isEmpty() {
121 return plainCache.isEmpty() && subnetCache.isEmpty();
125 public Iterable<EndpointForwardingTemplateBySubnet> values() {
126 return Iterables.unmodifiableIterable(Iterables.concat(plainCache.values(), subnetCache.values()));