Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
 /*
  * Copyright (C) 2011 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package pocketknife.internal;
An abstract supertype that provides memoization for idempotent operations that may be computed more than once, but for which performance is prohibitive. Subclasses implement the create(java.lang.Object) method with the operation to be memoized, while callers invoke the get(java.lang.Object) method to utilize the memoization.

Synchronization on this class is implemented using a java.util.concurrent.locks.ReadWriteLock. Multiple threads may accessed previously memoized results without contention.

This class is implemented such that concurrent requests for the same key may result in simultaneous computation in multiple threads - the instance of the result that is persisted for subsequent invocations in not guaranteed.

Warning: there is no eviction. Large input sets will result in growth without bound.

public abstract class Memoizer<K, V> {
    private final Map<K, V> map;
    private final Lock readLock;
    private final Lock writeLock;
    protected Memoizer() {
        // Don't use LinkedHashMap. This is a performance-oriented class and we don't want overhead
        this. = new HashMap<K, V>();
        ReadWriteLock lock = new ReentrantReadWriteLock();
        this. = lock.readLock();
        this. = lock.writeLock();
    }
    public final V get(K key) {
        if (key == null) {
            throw new NullPointerException("key == null");
        }
        // check to see if we already have a value
        .lock();
        try {
            V value = .get(key);
            if (value != null) {
                return value;
            }
        } finally {
            .unlock();
        }
        // create a new value.  this may race and we might create more than one instance, but that's ok
        V newValue = create(key);
        if (newValue == null) {
            throw new NullPointerException("create returned null");
        }
        // write the new value and return it
        .lock();
        try {
            .put(keynewValue);
            return newValue;
        } finally {
            .unlock();
        }
    }
    protected abstract V create(K key);
    @Override public final String toString() {
        .lock();
        try {
            return .toString();
        } finally {
            .unlock();
        }
    }
New to GrepCode? Check out our FAQ X