1 /*
2  * Copyright 2014-2020 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 package com.amazonaws.internal;
16
17 import java.util.concurrent.locks.ReentrantReadWriteLock;
18 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
19 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
20
21 import com.amazonaws.annotation.ThreadSafe;
22
23 /**
24  * A bounded cache that has a FIFO eviction policy when the cache is full.
25  *
26  * @param <T>
27  *            value type
28  */

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

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

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

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

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