View Javadoc

1   package com.atlassian.vcache;
2   
3   import java.util.Arrays;
4   import java.util.Collection;
5   import java.util.Map;
6   import java.util.Optional;
7   import java.util.function.Function;
8   import java.util.function.Supplier;
9   import javax.annotation.Nonnull;
10  
11  import com.atlassian.annotations.PublicApi;
12  
13  /**
14   * Represents the common operations that can be performed on a JVM local cache.
15   *
16   * @param <K> the key type
17   * @param <V> the value type
18   *
19   * @since 1.0
20   */
21  @PublicApi
22  public interface LocalCacheOperations<K, V>
23  {
24      /**
25       * Returns a value that is associated with a specified key.
26       *
27       * @param key the key to check.
28       * @return an {@link Optional} which may contain the value associated with the key.
29       */
30      @Nonnull
31      Optional<V> get(K key);
32  
33      /**
34       * Returns a value that may be associated with a specified key.
35       * <p>Notes:</p>
36       * <ul>
37       *     <li>
38       *         If no entry for the specified key exists, then the specified <tt>supplier</tt> is called to create
39       *         an entry in the cache, before it is returned.
40       *     </li>
41       *     <li>
42       *         The <tt>supplier</tt> implementation needs to be multi-thread safe as it may be called concurrently
43       *         if multiple threads call this method.
44       *     </li>
45       * </ul>
46       *
47       * @param key the key uniquely identifying the value to be retrieved
48       * @param supplier used to generate the value, if one does not exist already for the key. The supplier may not
49       *                 return {@code null}.
50       * @return the value associated with the key.
51       */
52      @Nonnull
53      V get(K key, Supplier<? extends V> supplier);
54  
55      /**
56       * Unconditionally puts the value under the specified key, and returns the previous value associated
57       * with the key (if one existed).
58       *
59       * @param key the key to put the data under
60       * @param value the value to associate with the key.
61       * @return an {@link Optional} which may contain the previous value associated with the key.
62       */
63      @Nonnull
64      Optional<V> put(K key, V value);
65  
66      /**
67       * Conditionally puts the value under the specified key, if no entry currently exists. Returns the current
68       * value associated with the key, if one currently exists.
69       *
70       * @param key the key to put the data under
71       * @param value the value to associate with the key.
72       * @return {@link Optional#EMPTY} is no entry previously existed, otherwise the {@link Optional} contains
73       *         the current value.
74       */
75      @Nonnull
76      Optional<V> putIfAbsent(K key, V value);
77  
78      /**
79       * Conditionally replaces the value associated with a key, iff:
80       * <ul>
81       *     <li>An entry already exists for the key</li>
82       *     <li>The current value matches the supplied <tt>currentValue</tt> using {@link Object#equals(Object)}</li>
83       * </ul>
84       *
85       * @param key the key to replace data under
86       * @param currentValue the current value to match
87       * @param newValue the replacement value
88       * @return whether the current value are replaced with the supplied <tt>newValue</tt>
89       */
90      boolean replaceIf(K key, V currentValue, V newValue);
91  
92      /**
93       * Conditionally removed an entry for a specified key, iff:
94       * <ul>
95       *     <li>An entry already exists for the key</li>
96       *     <li>The current value matches the supplied <tt>value</tt> using {@link Object#equals(Object)}</li>
97       * </ul>
98       *
99       * @param key the key of the entry to remove conditionally
100      * @param value the current value to match
101      * @return whether an entry was removed
102      */
103     boolean removeIf(K key, V value);
104 
105     /**
106      * Removes all the entries for the supplied keys. The same as calling {@link #remove(Iterable)} passing
107      * {@code Arrays.asList(keys)} as the argument.
108      *
109      * @param keys specifies the entries to be removed.
110      */
111     @SuppressWarnings("unchecked")
112     default void remove(K... keys)
113     {
114         remove(Arrays.asList(keys));
115     }
116 
117     /**
118      * Removes all the entries for the supplied keys.
119      *
120      * @param keys specifies the entries to be removed.
121      */
122     void remove(Iterable<K> keys);
123 
124     /**
125      * Removes all the entries in the cache.
126      */
127     void removeAll();
128 
129     /**
130      * Returns the values that are associated with the specified keys. It is equivalent to calling
131      * {@link #getBulk(Iterable)} passing {@code Arrays.asList(keys)} as the parameter.
132      *
133      * @param keys the keys to check.
134      * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have
135      * {@link Optional} which may contain the value associated with the key.
136      */
137     @SuppressWarnings("unchecked")
138     @Nonnull
139     default Map<K, Optional<V>> getBulk(K... keys)
140     {
141         return getBulk(Arrays.asList(keys));
142     }
143 
144     /**
145      * Returns the values that are associated with the specified keys.
146      *
147      * @param keys the keys to check.
148      * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have
149      *         {@link Optional} which may contain the value associated with the key.
150      */
151     @Nonnull
152     Map<K, Optional<V>> getBulk(Iterable<K> keys);
153 
154     /**
155      * Returns the values that are associated with the specified keys. It is equivalent to calling
156      * {@link #getBulk(Function, Iterable)} passing {@code factory} and {@code Arrays.asList(keys)} as the parameters.
157      * <p>Notes:</p>
158      * <ul>
159      *   <li>
160      *       If no entry for the specified key exists, then the specified <tt>factory</tt> is called, sequentially
161      *       using the current thread, to create an entry in the cache, before it is returned.
162      *   </li>
163      * </ul>
164      *
165      * @param factory used to generate the values for the keys that do not have entries. The factory must return a
166      *                map containing a non-null entry for each supplied key.
167      * @param keys     the keys to retrieve
168      * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have
169      * the value associated with the key.
170      */
171     @SuppressWarnings("unchecked")
172     @Nonnull
173     default Map<K, V> getBulk(Function<Collection<K>, Map<K, V>> factory, K... keys)
174     {
175         return getBulk(factory, Arrays.asList(keys));
176     }
177 
178     /**
179      * Returns the values that are associated with the specified keys.
180      * <p>Notes:</p>
181      * <ul>
182      *   <li>
183      *       If no entry for the specified key exists, then the specified <tt>factory</tt> is called, sequentially
184      *       using the current thread, to create an entry in the cache, before it is returned.
185      *   </li>
186      * </ul>
187      *
188      * @param factory used to generate the values for the keys that do not have entries. The factory must return a
189      *                map containing a non-null entry for each supplied key.
190      * @param keys     the keys to retrieve
191      * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have
192      * the value associated with the key.
193      */
194     @Nonnull
195     Map<K, V> getBulk(Function<Collection<K>, Map<K, V>> factory, Iterable<K> keys);
196 }