    001package com.hammurapi.store;
    002
    003import java.util.Collection;
    004import java.util.Comparator;
    005import java.util.Iterator;
    006import java.util.Map;
    007import java.util.concurrent.ExecutorService;
    008import java.util.concurrent.locks.Lock;
    009import java.util.concurrent.locks.ReadWriteLock;
    010
    011import com.hammurapi.common.concurrent.NonBlockingExecutorService;
    012import com.hammurapi.extract.Extractor;
    013import com.hammurapi.extract.Predicate;
    014import com.hammurapi.store.Index.Type;
    015
    016/**
    017 * This class operates on master's data. It uses master's locks and storage, and is aware if the master already holds a certain lock.
    018 * In this case this implementation doesn't acquire its own lock but operates
    019 * within master's lock because it acts on behalf of the master.
    020 * Attempt to acquire write lock if the master holds read lock results in exception.
    021 * Deputy stores are used by the AbstractStore implementations to operate in asynchronous tasks.
    022 * @author Pavel Vlasov
    023 *
    024 * @param <T>
    025 * @param <PK>
    026 */
    027public abstract class DeputyStore<T,PK,S extends Store<T,PK,S>> extends AbstractStore<T,PK,S> {
    028
    029        protected AbstractStore<T,PK,S> master;
    030        public int hashCode() {
    031                return master.hashCode();
    032        }
    033
    034        public Handle<T, PK, S> put(T obj) {
    035                return master.put(obj);
    036        }
    037
    038        public boolean equals(Object obj) {
    039                return master.equals(obj);
    040        }
    041
    042        public Iterable<T> getAll() {
    043                return master.getAll();
    044        }
    045
    046        public T getByPrimaryKey(PK primaryKey) {
    047                return master.getByPrimaryKey(primaryKey);
    048        }
    049
    050        public Iterable<T> get(Predicate<T, S> selector) {
    051                return master.get(selector);
    052        }
    053
    054        public <V> Iterable<V> get(
    055                        Predicate<T, S> selector,
    056                        Extractor<T, V, S> extractor,
    057                        boolean ordered,
    058                        Comparator<V> comparator) {
    059                return master.get(selector, extractor, ordered, comparator);
    060        }
    061
    062        public String toString() {
    063                return master.toString();
    064        }
    065
    066        public void clear() {
    067                master.clear();
    068        }
    069
    070        public boolean remove(T obj) {
    071                return master.remove(obj);
    072        }
    073
    074        public boolean removeByPrimaryKey(PK primaryKey) {
    075                return master.removeByPrimaryKey(primaryKey);
    076        }
    077
    078        public int remove(Predicate<T, S> selector) {
    079                return master.remove(selector);
    080        }
    081
    082        public int update(
    083                        Predicate<T, S> selector,
    084                        UpdateTask<T, PK, S> updater) {
    085
    086                return master.update(selector, updater);
    087        }
    088
    089        @Override
    090        public <V, ST extends T> Index<T, ST, PK, V, S> addIndex(
    091                        Predicate<T, S> predicate,
    092                        Extractor<ST, V, S> extractor,
    093                        Type type,
    094                        boolean ordered,
    095                        Comparator<V> comparator) {
    096
    097                return master.addIndex(predicate, extractor, type, ordered, comparator);
    098        }
    099
    100        public Extractor<T, PK, S> getPrimaryKeyExtractor() {
    101                return master.getPrimaryKeyExtractor();
    102        }
    103
    104        public int queryAll(QueryTask<T, PK, S> query) {
    105                return master.queryAll(query);
    106        }
    107
    108        public int query(
    109                        Predicate<T, S> selector,
    110                        QueryTask<T, PK, S> query) {
    111
    112                return master.query(selector, query);
    113        }
    114
    115        public Iterator<T> iterator() {
    116                return master.iterator();
    117        }
    118
    119        public S createView(Predicate<T, S> selector, ViewType viewType) {
    120                return master.createView(selector, viewType);
    121        }
    122
    123        public Lock readLock() {
    124                return masterLock.readLock();
    125        }
    126
    127        public Lock writeLock() {
    128                return masterLock.writeLock();
    129        }
    130
    131        private ReadWriteLock masterLock;
    132
    133        private NonBlockingExecutorService nonBlockingExecutorService;
    134
    135        /**
    136         * Creates deputy store.
    137         * @param master Master store.
    138         * @param masterLock Lock which delegates to master lock and can be used
    139         * from multiple threads/processes, i.e. the lock owner is not the current
    140         * thread but the master store.
    141         */
    142        public DeputyStore(AbstractStore<T,PK,S> master, ReadWriteLock masterLock) {
    143                this.master = master;
    144                this.masterLock = masterLock;
    145                if (master.getExecutorService() instanceof NonBlockingExecutorService) {
    146                        this.nonBlockingExecutorService = (NonBlockingExecutorService) master.getExecutorService();
    147                } else {
    148                        this.nonBlockingExecutorService = new NonBlockingExecutorService(master.getExecutorService());
    149                }
    150        }
    151
    152        @Override
    153        protected Map<PK, Handle<T, PK, S>> getPkStore() {
    154                return master.getPkStore();
    155        }
    156
    157        @Override
    158        protected Collection<Handle<T, PK, S>> getNoPkStore() {
    159                return master.getNoPkStore();
    160        }
    161
    162        @Override
    163        protected ExecutorService getExecutorService() {
    164                return nonBlockingExecutorService;
    165        }
    166
    167        @Override
    168        protected Handle<T, PK, S> createHandle(
    169                        T obj,
    170                        PK primaryKey,
    171                        Map<S, Map<Extractor<T, ? super PK, S>, ? super PK>> cache,
    172                        Predicate<T, S>[] validators) {
    173                return master.createHandle(obj, primaryKey, cache, validators);
    174        }
    175
    176        @Override
    177        protected Collection<Handle<T, PK, S>> createIndexCollection(boolean unique, boolean ordered, Comparator<T> comparator) {
    178                return master.createIndexCollection(unique, ordered, comparator);
    179        }
    180
    181        @Override
    182        protected Map<S, Map<Extractor<T, ? super PK, S>, ? super PK>> createCache() {
    183                return master.createCache();
    184        }
    185
    186        @Override
    187        protected ReadWriteLock createMasterLock() {
    188                if (masterLock instanceof DeputyReadWriteLock) {
    189                        return ((DeputyReadWriteLock) masterLock).createDeputy();
    190                }
    191
    192                throw new UnsupportedOperationException("Creating master locks from non-deputy locks is not implemented.");
    193        }
    194
    195        @Override
    196        protected void onRemoved(int removed) {
    197                master.onRemoved(removed);
    198        }
    199
    200        @Override
    201        protected Collection<AbstractIndex<T, ? extends T, PK, ?, S>> getIndices() {
    202                return master.getIndices();
    203        }
    204
    205        @Override
    206        protected <V, ST extends T> AbstractIndex<T, ST, PK, V, S> createIndex(
    207                        Predicate<T, S> predicate,
    208                        Extractor<ST, V, S> extractor, Type type,
    209                        boolean ordered, Comparator<V> comparator) {
    210                return master.createIndex(predicate, extractor, type, ordered, comparator);
    211        }
    212
    213        protected AbstractStore<T, PK, S> getMaster() {
    214                return master;
    215        }
    216}