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
8 package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao;
10 import com.google.common.base.Optional;
11 import com.google.common.collect.Iterables;
13 import java.util.concurrent.ConcurrentHashMap;
14 import java.util.concurrent.ConcurrentMap;
15 import java.util.regex.Pattern;
16 import javax.annotation.Nonnull;
17 import javax.annotation.Nullable;
18 import org.apache.commons.net.util.SubnetUtils;
19 import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
20 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.EPTemplateUtil;
21 import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SubnetInfoKeyDecorator;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
26 * Purpose: generic implementation of {@link SimpleCachedDao}
28 public class SimpleCachedDaoEPForwardingTemplateImpl implements SimpleCachedDao<IpPrefix, EndpointForwardingTemplateBySubnet> {
30 private final ConcurrentMap<IpPrefix, EndpointForwardingTemplateBySubnet> plainCache;
31 private final ConcurrentMap<SubnetInfoKeyDecorator, EndpointForwardingTemplateBySubnet> subnetCache;
32 private final Pattern IP_MASK_EATER_RE = Pattern.compile("/[0-9]+");
34 public SimpleCachedDaoEPForwardingTemplateImpl() {
35 plainCache = new ConcurrentHashMap<>();
36 subnetCache = new ConcurrentHashMap<>();
40 public EndpointForwardingTemplateBySubnet update(@Nonnull final IpPrefix key, @Nullable final EndpointForwardingTemplateBySubnet value) {
41 final EndpointForwardingTemplateBySubnet previousValue;
42 if (EPTemplateUtil.isPlain(key)) {
43 previousValue = updatePlainCache(key, value);
45 previousValue = updateSubnetCache(key, value);
51 private EndpointForwardingTemplateBySubnet updateSubnetCache(final IpPrefix key, final EndpointForwardingTemplateBySubnet value) {
52 final EndpointForwardingTemplateBySubnet previousValue;
53 final SubnetInfoKeyDecorator subnetKey = EPTemplateUtil.buildSubnetInfoKey(key);
55 previousValue = subnetCache.put(subnetKey, value);
57 previousValue = subnetCache.remove(subnetKey);
62 private EndpointForwardingTemplateBySubnet updatePlainCache(final @Nonnull IpPrefix key, final @Nullable EndpointForwardingTemplateBySubnet value) {
63 final EndpointForwardingTemplateBySubnet previousValue;
65 previousValue = plainCache.put(key, value);
67 previousValue = plainCache.remove(key);
73 public Optional<EndpointForwardingTemplateBySubnet> find(@Nonnull final IpPrefix key) {
74 final Optional<EndpointForwardingTemplateBySubnet> template;
75 if (EPTemplateUtil.isPlain(key)) {
76 final Optional<EndpointForwardingTemplateBySubnet> fastPlain = Optional.fromNullable(plainCache.get(key));
77 if (fastPlain.isPresent()) {
80 template = lookupSlowSubnet(key.getIpv4Prefix().getValue());
83 final SubnetInfoKeyDecorator keyDecorator = EPTemplateUtil.buildSubnetInfoKey(key);
84 final Optional<EndpointForwardingTemplateBySubnet> fastSubnet =
85 Optional.fromNullable(subnetCache.get(keyDecorator));
86 if (fastSubnet.isPresent()) {
87 template = fastSubnet;
89 template = Optional.absent();
95 private Optional<EndpointForwardingTemplateBySubnet> lookupSlowSubnet(final String value) {
96 final String plainIp = IP_MASK_EATER_RE.matcher(value).replaceFirst("");
97 EndpointForwardingTemplateBySubnet valueCandidate = null;
99 for (Map.Entry<SubnetInfoKeyDecorator, EndpointForwardingTemplateBySubnet> entry : subnetCache.entrySet()) {
100 final SubnetUtils.SubnetInfo subnetInfo = entry.getKey().getDelegate();
101 if (subnetInfo.isInRange(plainIp)) {
102 final int addressCountTmp = subnetInfo.getAddressCount();
103 if (valueCandidate == null || addressCount > addressCountTmp) {
104 valueCandidate = entry.getValue();
105 addressCount = addressCountTmp;
109 return Optional.fromNullable(valueCandidate);
113 public void invalidateCache() {
119 public boolean isEmpty() {
120 return plainCache.isEmpty() && subnetCache.isEmpty();
124 public Iterable<EndpointForwardingTemplateBySubnet> values() {
125 return Iterables.unmodifiableIterable(Iterables.concat(plainCache.values(), subnetCache.values()));