2 * Copyright (c) 2015 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.protocol.pcep.impl;
11 import com.google.common.base.Optional;
12 import com.google.common.cache.Cache;
13 import com.google.common.cache.CacheBuilder;
14 import java.util.Arrays;
15 import java.util.HashMap;
17 import java.util.concurrent.Callable;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.TimeUnit;
20 import javax.annotation.concurrent.GuardedBy;
21 import javax.annotation.concurrent.ThreadSafe;
24 final class PCEPPeerRegistry {
27 * The maximum lifetime for which we should hold on to a session ID before assuming it is okay to reuse it.
29 private static final long ID_CACHE_SECONDS = 3 * 3600;
32 * The total amount of time we should remember a peer having been present, unless some other pressure forces us to
33 * forget about it due to {@link PEER_CACHE_SIZE}.
35 private static final long PEER_CACHE_SECONDS = 24 * 3600;
38 * Maximum total number of peers we keep track of. Combined with {@link PEER_CACHE_SECONDS}, this defines how many
39 * peers we can see turn around.
41 private static final long PEER_CACHE_SIZE = 1024;
44 private final Cache<ByteArrayWrapper, PeerRecord> formerClients = CacheBuilder.newBuilder().expireAfterAccess(PEER_CACHE_SECONDS,
45 TimeUnit.SECONDS).maximumSize(PEER_CACHE_SIZE).build();
48 private final Map<ByteArrayWrapper, SessionReference> sessions = new HashMap<>();
50 protected interface SessionReference extends AutoCloseable {
55 protected synchronized Optional<SessionReference> getSessionReference(final byte[] clientAddress) {
56 final SessionReference sessionReference = this.sessions.get(new ByteArrayWrapper(clientAddress));
57 if (sessionReference != null) {
58 return Optional.of(sessionReference);
60 return Optional.absent();
63 protected synchronized Optional<SessionReference> removeSessionReference(final byte[] clientAddress) {
64 final SessionReference sessionReference = this.sessions.remove(new ByteArrayWrapper(clientAddress));
65 if (sessionReference != null) {
66 return Optional.of(sessionReference);
68 return Optional.absent();
71 protected synchronized void putSessionReference(final byte[] clientAddress, final SessionReference sessionReference) {
72 this.sessions.put(new ByteArrayWrapper(clientAddress), sessionReference);
75 protected synchronized Short nextSession(final byte[] clientAddress) throws ExecutionException {
76 final PeerRecord peer = this.formerClients.get(new ByteArrayWrapper(clientAddress), () -> new PeerRecord(ID_CACHE_SECONDS, null));
78 return peer.allocId();
81 protected synchronized void releaseSession(final byte[] clientAddress, final short sessionId) throws ExecutionException {
82 this.formerClients.get(new ByteArrayWrapper(clientAddress), () -> new PeerRecord(ID_CACHE_SECONDS, sessionId));
85 private static final class ByteArrayWrapper {
87 private final byte[] byteArray;
89 public ByteArrayWrapper(final byte[] byteArray) {
90 this.byteArray = byteArray == null ? null : byteArray.clone();
94 public int hashCode() {
95 return Arrays.hashCode(this.byteArray);
99 public boolean equals(final Object obj) {
103 if (!(obj instanceof ByteArrayWrapper)) {
106 return Arrays.equals(this.byteArray, ((ByteArrayWrapper) obj).byteArray);