1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */

15
16 package software.amazon.awssdk.auth.signer.internal;
17
18 import java.util.concurrent.locks.ReentrantReadWriteLock;
19 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
20 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
21 import software.amazon.awssdk.annotations.SdkInternalApi;
22 import software.amazon.awssdk.annotations.ThreadSafe;
23
24 /**
25  * A bounded cache that has a FIFO eviction policy when the cache is full.
26  *
27  * @param <T>
28  *            value type
29  */

30 @ThreadSafe
31 @SdkInternalApi
32 public final class FifoCache<T> {
33     private final BoundedLinkedHashMap<String, T> map;
34     private final ReadLock rlock;
35     private final WriteLock wlock;
36
37     /**
38      * @param maxSize
39      *            the maximum number of entries of the cache
40      */

41     public FifoCache(final int maxSize) {
42         if (maxSize < 1) {
43             throw new IllegalArgumentException("maxSize " + maxSize
44                                                + " must be at least 1");
45         }
46         map = new BoundedLinkedHashMap<>(maxSize);
47         ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
48         rlock = lock.readLock();
49         wlock = lock.writeLock();
50     }
51
52     /**
53      * Adds an entry to the cache, evicting the earliest entry if necessary.
54      */

55     public T add(String key, T value) {
56         wlock.lock();
57         try {
58             return map.put(key, value);
59         } finally {
60             wlock.unlock();
61         }
62     }
63
64     /** Returns the value of the given key; or null of no such entry exists. */
65     public T get(String key) {
66         rlock.lock();
67         try {
68             return map.get(key);
69         } finally {
70             rlock.unlock();
71         }
72     }
73
74     /**
75      * Returns the current size of the cache.
76      */

77     public int size() {
78         rlock.lock();
79         try {
80             return map.size();
81         } finally {
82             rlock.unlock();
83         }
84     }
85
86     /**
87      * Returns the maximum size of the cache.
88      */

89     public int getMaxSize() {
90         return map.getMaxSize();
91     }
92
93     @Override
94     public String toString() {
95         rlock.lock();
96         try {
97             return map.toString();
98         } finally {
99             rlock.unlock();
100         }
101     }
102 }
103