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 }