View Javadoc

1   package com.atlassian.vcache;
2   
3   import java.util.Arrays;
4   import java.util.Map;
5   import java.util.Optional;
6   import java.util.Set;
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.
57       *
58       * @param key the key to put the data under
59       * @param value the value to associate with the key.
60       */
61      void put(K key, V value);
62  
63      /**
64       * Conditionally puts the value under the specified key, if no entry currently exists. Returns the current
65       * value associated with the key, if one currently exists.
66       *
67       * @param key the key to put the data under
68       * @param value the value to associate with the key.
69       * @return {@link Optional#EMPTY} is no entry previously existed, otherwise the {@link Optional} contains
70       *         the current value.
71       */
72      @Nonnull
73      Optional<V> putIfAbsent(K key, V value);
74  
75      /**
76       * Conditionally replaces the value associated with a key, iff:
77       * <ul>
78       *     <li>An entry already exists for the key</li>
79       *     <li>The current value matches the supplied <tt>currentValue</tt> using {@link Object#equals(Object)}</li>
80       * </ul>
81       *
82       * @param key the key to replace data under
83       * @param currentValue the current value to match
84       * @param newValue the replacement value
85       * @return whether the current value are replaced with the supplied <tt>newValue</tt>
86       */
87      boolean replaceIf(K key, V currentValue, V newValue);
88  
89      /**
90       * Conditionally removed an entry for a specified key, iff:
91       * <ul>
92       *     <li>An entry already exists for the key</li>
93       *     <li>The current value matches the supplied <tt>value</tt> using {@link Object#equals(Object)}</li>
94       * </ul>
95       *
96       * @param key the key of the entry to remove conditionally
97       * @param value the current value to match
98       * @return whether an entry was removed
99       */
100     boolean removeIf(K key, V value);
101 
102     /**
103      * Removes all the entries for the supplied keys. The same as calling {@link #remove(Iterable)} passing
104      * {@code Arrays.asList(keys)} as the argument.
105      *
106      * @param keys specifies the entries to be removed.
107      */
108     @SuppressWarnings("unchecked")
109     default void remove(K... keys)
110     {
111         remove(Arrays.asList(keys));
112     }
113 
114     /**
115      * Removes all the entries for the supplied keys.
116      *
117      * @param keys specifies the entries to be removed.
118      */
119     void remove(Iterable<K> keys);
120 
121     /**
122      * Removes all the entries in the cache.
123      */
124     void removeAll();
125 
126     /**
127      * Returns the values that are associated with the specified keys. It is equivalent to calling
128      * {@link #getBulk(Iterable)} passing {@code Arrays.asList(keys)} as the parameter.
129      *
130      * @param keys the keys to check.
131      * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have
132      * {@link Optional} which may contain the value associated with the key.
133      */
134     @SuppressWarnings("unchecked")
135     @Nonnull
136     default Map<K, Optional<V>> getBulk(K... keys)
137     {
138         return getBulk(Arrays.asList(keys));
139     }
140 
141     /**
142      * Returns the values that are associated with the specified keys.
143      *
144      * @param keys the keys to check.
145      * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have
146      *         {@link Optional} which may contain the value associated with the key.
147      */
148     @Nonnull
149     Map<K, Optional<V>> getBulk(Iterable<K> keys);
150 
151     /**
152      * Returns the values that are associated with the specified keys. It is equivalent to calling
153      * {@link #getBulk(Function, Iterable)} passing {@code factory} and {@code Arrays.asList(keys)} as the parameters.
154      * <p>Notes:</p>
155      * <ul>
156      *   <li>
157      *       If no entry exists for a key (or keys), then the specified <tt>factory</tt> is called once
158      *       using the current thread passing in the missing keys to create the missing entries in the cache, before it is returned.
159      *   </li>
160      * </ul>
161      *
162      * @param factory used to generate the values for the keys that do not have entries. The factory must return a
163      *                map containing a non-null entry for each supplied key.
164      * @param keys     the keys to retrieve
165      * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have
166      * the value associated with the key.
167      */
168     @SuppressWarnings("unchecked")
169     @Nonnull
170     default Map<K, V> getBulk(Function<Set<K>, Map<K, V>> factory, K... keys)
171     {
172         return getBulk(factory, Arrays.asList(keys));
173     }
174 
175     /**
176      * Returns the values that are associated with the specified keys.
177      * <p>Notes:</p>
178      * <ul>
179      *   <li>
180      *       If no entry exists for a key (or keys), then the specified <tt>factory</tt> is called once
181      *       using the current thread passing in the missing keys to create the missing entries in the cache, before it is returned.
182      *   </li>
183      * </ul>
184      *
185      * @param factory used to generate the values for the keys that do not have entries. The factory must return a
186      *                map containing a non-null entry for each supplied key.
187      * @param keys     the keys to retrieve
188      * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have
189      * the value associated with the key.
190      */
191     @Nonnull
192     Map<K, V> getBulk(Function<Set<K>, Map<K, V>> factory, Iterable<K> keys);
193 }