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}