App Engine Java SDK version 1.9.8
[gae.git] / java / src / main / com / google / appengine / api / memcache / MemcacheService.java
blob541ff826bc40b63682a02a9e69969c410be27a69
1 // Copyright 2008 Google Inc. All rights reserved
3 package com.google.appengine.api.memcache;
5 import java.io.Serializable;
6 import java.util.Collection;
7 import java.util.Map;
8 import java.util.Objects;
9 import java.util.Set;
11 /**
12 * The Java API for the App Engine Memcache service. This offers a fast
13 * distributed cache for commonly-used data. The cache is limited both in
14 * duration and also in total space, so objects stored in it may be discarded
15 * at any time.
16 * <p>
17 * Note that {@code null} is a legal value to store in the cache, or to use
18 * as a cache key. Although the API is written for {@link Object}s, both
19 * keys and values should be {@link Serializable}, although future versions
20 * may someday accept specific types of non-{@code Serializable}
21 * {@code Objects}.
22 * <p>
23 * The values returned from this API are mutable copies from the cache;
24 * altering them has no effect upon the cached value itself until assigned with
25 * one of the {@link #put(Object, Object) put} methods. Likewise, the methods
26 * returning collections return mutable collections, but changes do not affect
27 * the cache.
28 * <p>
29 * Methods that operate on single entries, including {@link #increment}, are
30 * atomic, while batch methods such as {@link #getAll}, {@link #putAll}, and
31 * {@link #deleteAll} do not provide atomicity. Arbitrary operations on single
32 * entries can be performed atomically by using {@link #putIfUntouched} in
33 * combination with {@link #getIdentifiable}.
35 * <p>
36 * {@link #increment Increment} has a number of caveats to its use; please
37 * consult the method documentation.
40 public interface MemcacheService extends BaseMemcacheService {
42 /**
43 * Cache replacement strategies for {@link MemcacheService#put} operations,
44 * indicating how to handle putting a value that already exists.
46 enum SetPolicy {
47 /**
48 * Always stores the new value. If an existing value was stored with the
49 * given key, it will be discarded and replaced.
51 SET_ALWAYS,
53 /**
54 * An additive-only strategy, useful to avoid race conditions.
56 ADD_ONLY_IF_NOT_PRESENT,
58 /**
59 * A replace-only strategy.
61 REPLACE_ONLY_IF_PRESENT
64 /**
65 * Encapsulates an Object that is returned by {@link #getIdentifiable}.
66 * An {@code IdentifiableValue} can later be used in a {@link #putIfUntouched}
67 * operation.
69 interface IdentifiableValue {
70 /**
71 * @return the encapsulated value object.
73 Object getValue();
76 /**
77 * A holder for compare and set values.
78 * {@link Expiration expiration} and {@code newValue} can be null.
80 final class CasValues {
82 private final IdentifiableValue oldValue;
83 private final Object newValue;
84 private final Expiration expiration;
86 public CasValues(IdentifiableValue oldValue, Object newValue) {
87 this(oldValue, newValue, null);
90 public CasValues(IdentifiableValue oldValue, Object newValue, Expiration expiration) {
91 if (oldValue == null) {
92 throw new IllegalArgumentException("oldValue can not be null");
94 this.oldValue = oldValue;
95 this.newValue = newValue;
96 this.expiration = expiration;
99 public IdentifiableValue getOldValue() {
100 return oldValue;
103 public Object getNewValue() {
104 return newValue;
107 public Expiration getExipration() {
108 return expiration;
111 @Override
112 public boolean equals(Object otherObj) {
113 if (this == otherObj) {
114 return true;
116 if ((otherObj == null) || (getClass() != otherObj.getClass())) {
117 return false;
119 CasValues otherCasValues = (CasValues) otherObj;
120 return Objects.equals(oldValue, otherCasValues.oldValue) &&
121 Objects.equals(newValue, otherCasValues.newValue) &&
122 Objects.equals(expiration, otherCasValues.expiration);
125 @Override
126 public int hashCode() {
127 return Objects.hash(oldValue, newValue, expiration);
132 * @deprecated use {@link MemcacheServiceFactory#getMemcacheService(String)}
133 * instead.
135 @Deprecated
136 void setNamespace(String newNamespace);
139 * Fetches a previously-stored value, or {@code null} if unset. To
140 * distinguish a {@code null} value from unset use
141 * {@link MemcacheService#contains(Object)}.
143 * @param key the key object used to store the cache entry
144 * @return the value object previously stored, or {@code null}
145 * @throws IllegalArgumentException if {@code key} is not
146 * {@link Serializable} and is not {@code null}
147 * @throws InvalidValueException for any error in reconstituting the cache
148 * value.
150 Object get(Object key);
153 * Similar to {@link #get}, but returns an object that can later be used
154 * to perform a {@link #putIfUntouched} operation.
156 * @param key the key object used to store the cache entry
157 * @return an {@link IdentifiableValue} object that wraps the
158 * value object previously stored. {@code null} is returned if {@code key}
159 * is not present in the cache.
160 * @throws IllegalArgumentException if {@code key} is not
161 * {@link Serializable} and is not {@code null}
162 * @throws InvalidValueException for any error in reconstituting the cache
163 * value
165 IdentifiableValue getIdentifiable(Object key);
168 * Performs a getIdentifiable for multiple keys at once.
169 * This is more efficient than multiple separate calls to
170 * {@link #getIdentifiable(Object)}.
172 * @param keys a collection of keys for which values should be retrieved
173 * @return a mapping from keys to values of any entries found. If a requested
174 * key is not found in the cache, the key will not be in the returned Map.
175 * @throws IllegalArgumentException if any element of {@code keys} is not
176 * {@link Serializable} and is not {@code null}
177 * @throws InvalidValueException for any error in deserializing the cache
178 * value
180 <T> Map<T, IdentifiableValue> getIdentifiables(Collection<T> keys);
183 * Tests whether a given value is in cache, even if its value is {@code null}.
184 * <p>
185 * Note that, because an object may be removed from cache at any time, the
186 * following is not sound code:
187 * <pre>
188 * if (memcache.contains("key")) {
189 * foo = memcache.get("key");
190 * if (foo == null) {
191 * // continue, assuming foo had the real value null
194 * </pre>
195 * The problem is that the cache could have dropped the entry between the
196 * call to {@link #contains} and {@link #get(Object)}. This is
197 * a sounder pattern:
198 * <pre>
199 * foo = memcache.get("key");
200 * if (foo == null) {
201 * if (memcache.contains("key")) {
202 * // continue, assuming foo had the real value null
203 * } else {
204 * // continue; foo may have had a real null, but has been dropped now
207 * </pre>
208 * Another alternative is to prefer {@link #getAll(Collection)}, although
209 * it requires making an otherwise-unneeded {@code Collection} of some sort.
211 * @param key the key object used to store the cache entry
212 * @return {@code true} if the cache contains an entry for the key
213 * @throws IllegalArgumentException if {@code key} is not
214 * {@link Serializable} and is not {@code null}
216 boolean contains(Object key);
219 * Performs a get of multiple keys at once. This is more efficient than
220 * multiple separate calls to {@link #get(Object)}, and allows a single
221 * call to both test for {@link #contains(Object)} and also fetch the value,
222 * because the return will not include mappings for keys not found.
224 * @param keys a collection of keys for which values should be retrieved
225 * @return a mapping from keys to values of any entries found.
226 * If a requested key is not found in the cache, the key will not be in
227 * the returned Map.
228 * @throws IllegalArgumentException if any element of {@code keys} is not
229 * {@link Serializable} and is not {@code null}
230 * @throws InvalidValueException for any error in deserializing the cache
231 * value
233 <T> Map<T, Object> getAll(Collection<T> keys);
236 * Store a new value into the cache, using {@code key}, but subject to the
237 * {@code policy} regarding existing entries.
239 * @param key the key for the new cache entry
240 * @param value the value to be stored
241 * @param expires an {@link Expiration} object to set time-based expiration.
242 * {@code null} may be used indicate no specific expiration.
243 * @param policy Requests particular handling regarding pre-existing entries
244 * under the same key. This parameter must not be {@code null}.
245 * @return {@code true} if a new entry was created, {@code false} if not
246 * because of the {@code policy}
247 * @throws IllegalArgumentException if {@code key} or {@code value} is not
248 * {@link Serializable} and is not {@code null}
249 * @throws MemcacheServiceException if server responds with an error and a
250 * {@link ConsistentErrorHandler} is not configured
252 boolean put(Object key, Object value, Expiration expires, SetPolicy policy);
255 * Convenience put, equivalent to {@link #put(Object,Object,Expiration,
256 * SetPolicy) put(key, value, expiration, SetPolicy.SET_ALWAYS)}.
258 * @param key key of the new entry
259 * @param value value for the new entry
260 * @param expires time-based {@link Expiration}, or {@code null} for none
261 * @throws IllegalArgumentException if {@code key} or {@code value} is not
262 * {@link Serializable} and is not {@code null}
263 * @throws MemcacheServiceException if server responds with an error and a
264 * {@link ConsistentErrorHandler} is not configured
266 void put(Object key, Object value, Expiration expires);
269 * A convenience shortcut, equivalent to {@link #put(Object,Object,
270 * Expiration,SetPolicy) put(key, value, null, SetPolicy.SET_ALWAYS)}.
272 * @param key key of the new entry
273 * @param value value for the new entry
274 * @throws IllegalArgumentException if {@code key} or {@code value} is not
275 * {@link Serializable} and is not {@code null}
276 * @throws MemcacheServiceException if server responds with an error and a
277 * {@link ConsistentErrorHandler} is not configured
279 void put(Object key, Object value);
282 * A batch-processing variant of {@link #put}. This is more efficiently
283 * implemented by the service than multiple calls.
285 * @param values the key/value mappings to add to the cache
286 * @param expires the expiration time for all {@code values}, or
287 * {@code null} for no time-based expiration.
288 * @param policy what to do if the entry is or is not already present
289 * @return the set of keys for which entries were created. Keys in
290 * {@code values} may not be in the returned set because of the
291 * {@code policy} regarding pre-existing entries.
292 * @throws IllegalArgumentException if any of the keys or values are not
293 * {@link Serializable} and are not {@code null}
294 * @throws MemcacheServiceException if server responds with an error for any
295 * of the given values
297 <T> Set<T> putAll(Map<T, ?> values, Expiration expires, SetPolicy policy);
300 * Convenience multi-put, equivalent to {@link #putAll(Map,Expiration,
301 * SetPolicy) putAll(values, expires, SetPolicy.SET_ALWAYS)}.
303 * @param values key/value mappings to add to the cache
304 * @param expires expiration time for the new values, or {@code null} for no
305 * time-based expiration
306 * @throws IllegalArgumentException if any of the keys or values are not
307 * {@link Serializable} and are not {@code null}
308 * @throws MemcacheServiceException if server responds with an error for any
309 * of the given values
311 void putAll(Map<?, ?> values, Expiration expires);
314 * Convenience multi-put, equivalent to {@link #putAll(Map,Expiration,
315 * SetPolicy) putAll(values, expires, SetPolicy.SET_ALWAYS)}.
317 * @param values key/value mappings for new entries to add to the cache
318 * @throws IllegalArgumentException if any of the keys or values are not
319 * {@link Serializable} and are not {@code null}
320 * @throws MemcacheServiceException if server responds with an error for any
321 * of the given values
323 void putAll(Map<?, ?> values);
326 * Atomically, store {@code newValue} only if no other value has been stored
327 * since {@code oldValue} was retrieved. {@code oldValue} is an
328 * {@link IdentifiableValue} that was returned from a previous call to
329 * {@link #getIdentifiable}.
330 * <p>
331 * If another value in the cache for {@code key} has been stored, or if
332 * this cache entry has been evicted, then nothing is stored by this call and
333 * {@code false} is returned.
334 * <p>
335 * Note that storing the same value again <i>does</i> count as a "touch" for
336 * this purpose.
337 * <p>
338 * Using {@link #getIdentifiable} and {@link #putIfUntouched} together
339 * constitutes an operation that either succeeds atomically or fails due to
340 * concurrency (or eviction), in which case the entire operation can be
341 * retried by the application.
343 * @param key key of the entry
344 * @param oldValue identifier for the value to compare against newValue
345 * @param newValue new value to store if oldValue is still there
346 * @param expires an {@link Expiration} object to set time-based expiration.
347 * {@code null} may be used to indicate no specific expiration.
348 * @return {@code true} if {@code newValue} was stored,
349 * {@code false} otherwise
350 * @throws IllegalArgumentException if {@code key} or {@code newValue} is
351 * not {@link Serializable} and is not {@code null}. Also throws
352 * IllegalArgumentException if {@code oldValue} is {@code null}.
353 * @throws MemcacheServiceException if server responds with an error and a
354 * {@link ConsistentErrorHandler} is not configured
356 boolean putIfUntouched(Object key, IdentifiableValue oldValue,
357 Object newValue, Expiration expires);
360 * Convenience shortcut, equivalent to {@link #putIfUntouched(Object,
361 * IdentifiableValue,Object,Expiration) put(key, oldValue, newValue, null)}.
363 * @param key key of the entry
364 * @param oldValue identifier for the value to compare against newValue
365 * @param newValue new value to store if oldValue is still there
366 * @return {@code true} if {@code newValue} was stored,
367 * {@code false} otherwise.
368 * @throws IllegalArgumentException if {@code key} or {@code newValue} is
369 * not {@link Serializable} and is not {@code null}. Also throws
370 * IllegalArgumentException if {@code oldValue} is {@code null}.
371 * @throws MemcacheServiceException if server responds with an error and a
372 * {@link ConsistentErrorHandler} is not configured
374 boolean putIfUntouched(Object key, IdentifiableValue oldValue, Object newValue);
377 * Convenience shortcut, equivalent to
378 * {@link #putIfUntouched(Map, Expiration) putIfUntouched(values, null)}.
380 * @param values the key/values mappings to compare and swap
381 * @return the set of keys for which the new value was stored.
382 * @throws IllegalArgumentException if any of the keys are not
383 * {@link Serializable} or any of the values are not {@link Serializable}
384 * or {@code null}
385 * @throws IllegalArgumentException If any of the keys or newValues are not
386 * {@link Serializable} and are not {@code null}. Also throws
387 * IllegalArgumentException if {@code values} has any nulls.
388 * @throws MemcacheServiceException if server responds with an error for any
389 * of the given {@code values} and a {@link ConsistentErrorHandler} is not
390 * configured
392 <T> Set<T> putIfUntouched(Map<T, CasValues> values);
395 * A batch-processing variant of {@link #putIfUntouched(Object,
396 * IdentifiableValue,Object,Expiration)}. This is more efficient than
397 * multiple single value calls.
399 * @param values the key/values mappings to compare and swap
400 * @param expiration an {@link Expiration} object to set time-based
401 * expiration for a {@link CasValues value} with a {@code null}
402 * {@link Expiration expiration} value.
403 * {@code null} may be used to indicate no specific expiration.
404 * @return the set of keys for which the new value was stored.
405 * @throws IllegalArgumentException If any of the keys or newValues are not
406 * {@link Serializable} and are not {@code null}. Also throws
407 * IllegalArgumentException if {@code values} has any nulls.
408 * @throws MemcacheServiceException if server responds with an error for any
409 * of the given {@code values} and a {@link ConsistentErrorHandler} is not
410 * configured
412 <T> Set<T> putIfUntouched(Map<T, CasValues> values, Expiration expiration);
415 * Removes {@code key} from the cache.
417 * @param key the key of the entry to delete.
418 * @return {@code true} if an entry existed, but was discarded
419 * @throws IllegalArgumentException if {@code key} is not
420 * {@link Serializable} and is not {@code null}
422 boolean delete(Object key);
425 * Removes the given key from the cache, and prevents it from being added
426 * under the {@link SetPolicy#ADD_ONLY_IF_NOT_PRESENT} policy for
427 * {@code millisNoReAdd} milliseconds thereafter. Calls to a {@link #put}
428 * method using {@link SetPolicy#SET_ALWAYS} are not blocked, however.
430 * @param key key to delete
431 * @param millisNoReAdd time during which calls to put using
432 * ADD_IF_NOT_PRESENT should be denied.
433 * @return {@code true} if an entry existed to delete
434 * @throws IllegalArgumentException if {@code key} is not
435 * {@link Serializable} and is not {@code null}
437 boolean delete(Object key, long millisNoReAdd);
440 * Batch version of {@link #delete(Object)}.
442 * @param keys a collection of keys for entries to delete
443 * @return the Set of keys deleted. Any keys in {@code keys} but not in the
444 * returned set were not found in the cache. The iteration order of the
445 * returned set matches the iteration order of the provided {@code keys}.
446 * @throws IllegalArgumentException if any element of {@code keys} is not
447 * {@link Serializable} and is not {@code null}
449 <T> Set<T> deleteAll(Collection<T> keys);
452 * Batch version of {@link #delete(Object, long)}.
454 * @param keys a collection of keys for entries to delete
455 * @param millisNoReAdd time during which calls to put using
456 * {@link SetPolicy#ADD_ONLY_IF_NOT_PRESENT} should be denied.
457 * @return the Set of keys deleted. Any keys in {@code keys} but not in the
458 * returned set were not found in the cache. The iteration order of the
459 * returned set matches the iteration order of the provided {@code keys}.
460 * @throws IllegalArgumentException if any element of {@code keys} is not
461 * {@link Serializable} and is not {@code null}
463 <T> Set<T> deleteAll(Collection<T> keys, long millisNoReAdd);
466 * Atomically fetches, increments, and stores a given integral value.
467 * "Integral" types are {@link Byte}, {@link Short}, {@link Integer},
468 * {@link Long}, and in some cases {@link String}. The entry must already
469 * exist, and have a non-negative value.
470 * <p>
471 * Incrementing by positive amounts will reach signed 64-bit max (
472 * {@code 2^63 - 1}) and then wrap-around to signed 64-bit min ({@code -2^63}
473 * ), continuing increments from that point.
474 * <p>
475 * To facilitate use as an atomic countdown, incrementing by a negative value
476 * (i.e. decrementing) will not go below zero: incrementing {@code 2} by
477 * {@code -5} will return {@code 0}, not {@code -3}.
478 * <p>
479 * Note: The actual representation of all numbers in Memcache is a string.
480 * This means if you initially stored a number as a string (e.g., "10") and
481 * then increment it, everything will work properly.
482 * <p>
483 * When you {@link #get(Object)} a key for a string value, wrapping occurs
484 * after exceeding the max value of an unsigned 64-bit number
485 * ({@code 2^64 - 1}). When you {@link #get(Object)} a key
486 * for a numerical type, wrapping occurs after exceeding the type max value.
488 * @param key the key of the entry to manipulate
489 * @param delta the size of the increment, positive or negative
490 * @return the post-increment value, as a long. However, a
491 * {@link #get(Object)} of the key will still have the original type (
492 * {@link Byte}, {@link Short}, etc.). If there is no entry for
493 * {@code key}, returns {@code null}.
494 * @throws IllegalArgumentException if {@code key} is not
495 * {@link Serializable} and is not {@code null}
496 * @throws InvalidValueException if the object incremented is not of a
497 * integral type or holding a negative value
499 Long increment(Object key, long delta);
502 * Like normal increment, but allows for an optional initial value for the
503 * key to take on if not already present in the cache.
504 * <p>
505 * Note, the provided initial value can be negative, which allows incrementing
506 * negative numbers. This is in contrast to the base version of this method,
507 * which requires a pre-existing value (e.g. one stored with {@link #put}) to
508 * be non-negative prior to being incremented.
510 * @param initialValue value to insert into the cache if the key is not
511 * present
512 * @see #increment(Object, long)
514 Long increment(Object key, long delta, Long initialValue);
517 * Like normal increment, but increments a batch of separate keys in
518 * parallel by the same delta.
520 * @return mapping keys to their new values; values will be null if they
521 * could not be incremented or were not present in the cache
523 <T> Map<T, Long> incrementAll(Collection<T> keys, long delta);
526 * Like normal increment, but increments a batch of separate keys in
527 * parallel by the same delta and potentially sets a starting value.
529 * @param initialValue value to insert into the cache if the key is not
530 * present
531 * @return mapping keys to their new values; values will be null if they
532 * could not be incremented for whatever reason
534 <T> Map<T, Long> incrementAll(Collection<T> keys, long delta, Long initialValue);
537 * Like normal increment, but accepts a mapping of separate controllable
538 * offsets for each key individually. Good for incrementing by a sum and
539 * a count in parallel.
541 * @return mapping keys to their new values; values will be null if they
542 * could not be incremented for whatever reason
544 <T> Map<T, Long> incrementAll(Map<T, Long> offsets);
547 * Like normal increment, but accepts a mapping of separate controllable
548 * offsets for each key individually. Good for incrementing by a sum and
549 * a count in parallel. Callers may also pass an initial value for the keys
550 * to take on if they are not already present in the cache.
552 * @return mapping keys to their new values; values will be null if they
553 * could not be incremented for whatever reason
555 <T> Map<T, Long> incrementAll(Map<T, Long> offsets, Long initialValue);
558 * Empties the cache of all values. Statistics are not affected.
559 * Note that this method flushes the cache for all namespaces.
561 void clearAll();
564 * Fetches some statistics about the cache and its usage.
566 * @return statistics for the cache. Note that this method returns
567 * aggregated {@link Stats} for all namespaces. Response will never be
568 * {@code null}.
570 Stats getStatistics();