001package org.cache2k.processor;
002
003/*
004 * #%L
005 * cache2k API
006 * %%
007 * Copyright (C) 2000 - 2016 headissue GmbH, Munich
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023/**
024 * An invokable function to perform an atomic operation on a cache entry. The entry
025 * processor is called via {@link org.cache2k.Cache#invoke} or
026 * {@link org.cache2k.Cache#invokeAll}.
027 *
028 * <p>With the entry processor it is possible to realize arbitrary operation
029 * semantics for an entry. For example, the method {@link org.cache2k.Cache#replaceIfEquals}
030 * can be expressed with the entry processor as follows:
031 *
032 *  <pre> {@code
033 *
034 *    public boolean replaceIfEquals(final K key, final V oldValue, final V newValue) {
035 *      EntryProcessor<K, V, Boolean> p = new EntryProcessor<K, V, Boolean>() {
036 *        public Boolean process(MutableCacheEntry<K, V> entry) throws Exception {
037 *          if (!entry.exists()) {
038 *            return false;
039 *          }
040 *          if (oldValue == null) {
041 *            if (null != entry.getValue()) {
042 *              return false;
043 *            }
044 *          } else {
045 *            if (!oldValue.equals(entry.getValue())) {
046 *              return false;
047 *            }
048 *          }
049 *          entry.setValue(newValue);
050 *          return true;
051 *        }
052 *      };
053 *      return cache.invoke(key, p);
054 *    }
055 * }</pre>
056 *
057 * <p>For effects on the loader and writer and further details consult the documentation
058 * on the {@link MutableCacheEntry}
059 *
060 * @author Jens Wilke
061 * @see MutableCacheEntry
062 * @see org.cache2k.Cache#invoke
063 * @see org.cache2k.Cache#invokeAll
064 */
065public interface EntryProcessor<K, V, R> {
066
067  /**
068   * Examines or mutates an entry.
069   *
070   * <p>From inside this method it is illegal to call methods on the same cache. This
071   * may cause a deadlock.
072   *
073   * <p>The method may not have any side effects except on the processed entry.
074   * The cache may call the method multiple times for each invocation via the cache, when needed.
075   *
076   * @param entry the entry to examine or mutate. The reference is only valid within a method call,
077   *              don't pass or store it
078   * @return a user defined result, that will be passed through and returned
079   * @throws Exception an arbitrary exception that will be wrapped into a {@link EntryProcessingException}
080   */
081  R process(MutableCacheEntry<K, V> entry) throws Exception;
082
083}