001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2012-2012 Pentaho and others
008// All Rights Reserved.
009*/
010package mondrian.rolap.cache;
011
012import java.util.Iterator;
013import java.util.Map.Entry;
014import java.util.concurrent.locks.*;
015
016/**
017 * A base implementation of the {@link SmartCache} interface which
018 * enforces synchronization with a ReadWrite lock.
019 */
020public abstract class SmartCacheImpl<K, V>
021    implements SmartCache<K, V>
022{
023    private final ReadWriteLock lock = new ReentrantReadWriteLock();
024
025    /**
026     * Must provide an iterator on the contents of the cache.
027     * It does not need to be thread safe because we will handle
028     * that in {@link SmartCacheImpl}.
029     */
030    protected abstract Iterator<Entry<K, V>> iteratorImpl();
031
032    protected abstract V putImpl(K key, V value);
033    protected abstract V getImpl(K key);
034    protected abstract V removeImpl(K key);
035    protected abstract void clearImpl();
036    protected abstract int sizeImpl();
037
038    public V put(K key, V value) {
039        lock.writeLock().lock();
040        try {
041            return putImpl(key, value);
042        } finally {
043            lock.writeLock().unlock();
044        }
045    }
046
047    public V get(K key) {
048        lock.readLock().lock();
049        try {
050            return getImpl(key);
051        } finally {
052            lock.readLock().unlock();
053        }
054    }
055
056    public V remove(K key) {
057        lock.writeLock().lock();
058        try {
059            return removeImpl(key);
060        } finally {
061            lock.writeLock().unlock();
062        }
063    }
064
065    public void clear() {
066        lock.writeLock().lock();
067        try {
068            clearImpl();
069        } finally {
070            lock.writeLock().unlock();
071        }
072    }
073
074    public int size() {
075        lock.readLock().lock();
076        try {
077            return sizeImpl();
078        } finally {
079            lock.readLock().unlock();
080        }
081    }
082
083    public void execute(SmartCache.SmartCacheTask<K, V> task) {
084        lock.writeLock().lock();
085        try {
086            task.execute(iteratorImpl());
087        } finally {
088            lock.writeLock().unlock();
089        }
090    }
091}
092// End SmartCacheImpl.java