17911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp/**
27911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * Copyright (c) 2012, Google Inc.
37911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp *
47911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * Licensed under the Apache License, Version 2.0 (the "License");
57911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * you may not use this file except in compliance with the License.
67911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * You may obtain a copy of the License at
77911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp *
87911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp *     http://www.apache.org/licenses/LICENSE-2.0
97911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp *
107911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * Unless required by applicable law or agreed to in writing, software
117911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * distributed under the License is distributed on an "AS IS" BASIS,
127911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * See the License for the specific language governing permissions and
147911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * limitations under the License.
157911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp */
167911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
177911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
187911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyppackage com.android.mail.utils;
197911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
207911d99fd35610f526dbdfc0a8529aaf87cac0c6mindypimport com.google.common.collect.Lists;
217911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
227911d99fd35610f526dbdfc0a8529aaf87cac0c6mindypimport java.util.Deque;
237911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
247911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp/**
257911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * This class maintains a cache of soft references to objects.  This allows callers to use a pool
267911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * of object instances
277911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp * @param <T>
287911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp */
297911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyppublic class ObjectCache<T> {
307911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    public interface Callback<T> {
317911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        T newInstance();
327911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        void onObjectReleased(T object);
337911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    }
347911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
357911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    private final Deque<T> mDataStore = Lists.newLinkedList();
367911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
377911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    private final Callback<T> mCallback;
387911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    private final int mMaxSize;
397911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
407911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    /**
417911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     * Creates a new ObjectCache instance
427911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     * @param callbacks Callback object that that will return a new instance of the object, and
437911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     *        perform any cleanup when the object is released back to the cache
447911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     */
457911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    public ObjectCache(Callback<T> callbacks, int maxSize) {
467911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        mCallback = callbacks;
477911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        mMaxSize = maxSize;
487911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    }
497911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
507911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    /**
517911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     * Returns an instance of the specified object type, creating a new instance if needed.
527911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     */
537911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    public T get() {
547911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        T result;
557911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        synchronized (mDataStore) {
567911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp            result = mDataStore.poll();
577911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        }
587911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        if (result == null) {
597911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp            result = mCallback.newInstance();
607911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        }
617911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        return result;
627911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    }
637911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp
647911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    /**
657911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     * Releases the specified object back to the cache.  Once an object is released, it can be
667911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     * returned by subsequent calls to get()
677911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp     */
687911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    public void release(T objectToCache) {
697911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        synchronized (mDataStore) {
707911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp            if (mDataStore.size() < mMaxSize) {
717911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp                mCallback.onObjectReleased(objectToCache);
727911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp                mDataStore.add(objectToCache);
737911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp            }
747911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp        }
757911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp    }
767911d99fd35610f526dbdfc0a8529aaf87cac0c6mindyp}
77