EMMA Coverage Report (generated Tue Apr 17 08:51:20 BST 2007)
[all classes][org.jtoolkit.essence.data.impl]

COVERAGE SUMMARY FOR SOURCE FILE [MemoryStore.java]

nameclass, %method, %block, %line, %
MemoryStore.java100% (1/1)89%  (17/19)63%  (420/666)73%  (100.6/137)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MemoryStore100% (1/1)89%  (17/19)63%  (420/666)73%  (100.6/137)
firstKey (): Object 0%   (0/1)0%   (0/38)0%   (0/6)
removeFirst (): Object 0%   (0/1)0%   (0/42)0%   (0/7)
doRemove (Object, boolean, Object): Object 100% (1/1)34%  (34/100)39%  (9/23)
first (): Object 100% (1/1)59%  (24/41)68%  (4/6)
remove (Object): Object 100% (1/1)70%  (23/33)91%  (7.2/8)
clear (): void 100% (1/1)72%  (13/18)95%  (5.7/6)
getSize (): int 100% (1/1)74%  (14/19)93%  (3.7/4)
keySet (): Set 100% (1/1)74%  (14/19)93%  (3.7/4)
values (): Collection 100% (1/1)74%  (14/19)93%  (3.7/4)
orderedValues (): Collection 100% (1/1)74%  (37/50)81%  (7.3/9)
containsKey (Object): boolean 100% (1/1)75%  (15/20)94%  (3.8/4)
containsValue (Object): boolean 100% (1/1)75%  (15/20)94%  (3.8/4)
get (Object): Object 100% (1/1)75%  (15/20)94%  (3.8/4)
visit (Visitor): Object 100% (1/1)77%  (23/30)94%  (7.5/8)
doPut (Object, Object, boolean, boolean): Object 100% (1/1)83%  (88/106)88%  (18.4/21)
MemoryStore (String, Store$CollectionType, DataValueClass, DataValueClass): void 100% (1/1)100% (9/9)100% (2/2)
MemoryStore (String, Store$CollectionType, DataValueClass, DataValueClass, St... 100% (1/1)100% (40/40)100% (8/8)
asMap (): Map 100% (1/1)100% (21/21)100% (4/4)
put0 (Object, Object): void 100% (1/1)100% (21/21)100% (5/5)

1package org.jtoolkit.essence.data.impl;
2 
3import org.jetbrains.annotations.NotNull;
4import org.jetbrains.annotations.Nullable;
5import org.jtoolkit.essence.app.pojo.impl.DataValueClass;
6import org.jtoolkit.essence.concurrency.Concurrency;
7import org.jtoolkit.essence.concurrency.ThreadSafe;
8import org.jtoolkit.essence.data.Store;
9import org.jtoolkit.essence.data.Transaction;
10import static org.jtoolkit.essence.data.Transaction.include;
11import static org.jtoolkit.essence.data.Transaction.isTransactional;
12import org.jtoolkit.essence.data.Visitor;
13import org.jtoolkit.essence.data.VisitorException;
14import org.jtoolkit.essence.utils.RWLock;
15 
16import java.util.*;
17import java.util.concurrent.ConcurrentHashMap;
18import java.util.concurrent.ConcurrentMap;
19import java.util.concurrent.locks.Lock;
20import java.util.concurrent.locks.ReadWriteLock;
21/*
22   Copyright 2006 Peter Lawrey
23 
24   Licensed under the Apache License, Version 2.0 (the "License");
25   you may not use this file except in compliance with the License.
26   You may obtain a copy of the License at
27 
28       http://www.apache.org/licenses/LICENSE-2.0
29 
30   Unless required by applicable law or agreed to in writing, software
31   distributed under the License is distributed on an "AS IS" BASIS,
32   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33   See the License for the specific language governing permissions and
34   limitations under the License.
35*/
36 
37/**
38 * @author Peter Lawrey
39 * @noinspection unchecked,RedundantCast,SuspiciousMethodCalls
40 */
41@ThreadSafe(Concurrency.CONCURRENT_READ_WRITE)
42public class MemoryStore<K, V> extends AbstractStore<K, V> {
43    private final ConcurrentMap<K, V> map = new ConcurrentHashMap<K, V>(256, 0.5f, 64);
44    private final ReadWriteLock lock = RWLock.createLock("memoryStore");
45    @Nullable private final SortedSet<K> queue;
46 
47    // Note used in container-test.
48    public MemoryStore(@NotNull String name, @NotNull CollectionType collectionType, @Nullable DataValueClass<K> keyClass, @NotNull DataValueClass<V> valueClass) {
49        this(name, collectionType, keyClass, valueClass, ReadMode.NONE, PersistMode.NONE);
50    }
51 
52    protected MemoryStore(@NotNull String name, @NotNull CollectionType collectionType, @Nullable DataValueClass<K> keyClass, @NotNull DataValueClass<V> valueClass, @NotNull ReadMode readMode, @NotNull PersistMode persistMode) {
53        super(name, collectionType, keyClass, valueClass, new ListenerSetImpl(), readMode, persistMode);
54        listenerSet.notifyReset(true);
55        if (isQueue)
56            queue = new TreeSet<K>();
57        else
58            queue = null;
59    }
60 
61    // accessible via JMX/reflection.
62    protected int getSize() {
63        Lock nonexclusiveLock = lock.readLock();
64        try {
65            nonexclusiveLock.lock();
66            return map.size();
67        } finally {
68            nonexclusiveLock.unlock();
69        }
70    }
71 
72    @NotNull public Map<K, V> asMap() {
73        Lock nonexclusiveLock = lock.readLock();
74        try {
75            nonexclusiveLock.lock();
76            return new LinkedHashMap<K, V>(map);
77        } finally {
78            nonexclusiveLock.unlock();
79        }
80    }
81 
82    @SuppressWarnings({"SuspiciousMethodCalls"})
83    protected boolean containsKey(@NotNull Object key) {
84        Lock nonexclusiveLock = lock.readLock();
85        try {
86            nonexclusiveLock.lock();
87            return map.containsKey(key);
88        } finally {
89            nonexclusiveLock.unlock();
90        }
91    }
92 
93    protected boolean containsValue(@NotNull Object value) {
94        Lock nonexclusiveLock = lock.readLock();
95        try {
96            nonexclusiveLock.lock();
97            return map.containsValue(value);
98        } finally {
99            nonexclusiveLock.unlock();
100        }
101    }
102 
103    protected void clear() {
104        Lock exclusiveLock = lock.writeLock();
105        try {
106            exclusiveLock.lock();
107            map.clear();
108        } finally {
109            exclusiveLock.unlock();
110        }
111    }
112 
113    @Nullable protected V first() {
114        Lock exclusiveLock = lock.writeLock();
115        try {
116            exclusiveLock.lock();
117            if (map.isEmpty())
118                return null;
119            return map.get(queue == null ? map.keySet().iterator().next() : queue.first());
120        } finally {
121            exclusiveLock.unlock();
122        }
123    }
124 
125    @Nullable protected K firstKey() {
126        Lock exclusiveLock = lock.writeLock();
127        try {
128            exclusiveLock.lock();
129            if (map.isEmpty())
130                return null;
131            return queue == null ? map.keySet().iterator().next() : queue.first();
132        } finally {
133            exclusiveLock.unlock();
134        }
135    }
136 
137    @Nullable protected V get(Object key) {
138// don't check for speed and to allow a get() after closed.
139//        checkKey(key);
140        Lock nonexclusiveLock = lock.readLock();
141        try {
142            nonexclusiveLock.lock();
143            return map.get(key);
144        } finally {
145            nonexclusiveLock.unlock();
146        }
147    }
148 
149    @NotNull protected Set<K> keySet() {
150        Lock exclusiveLock = lock.writeLock();
151        try {
152            exclusiveLock.lock();
153            return map.keySet();
154        } finally {
155            exclusiveLock.unlock();
156        }
157    }
158 
159    @Nullable protected V doPut(K key, V value, boolean ifAbsent, boolean ifPresent) {
160        checkWrite();
161        checkKey(key);
162        checkValue(value);
163        boolean exclusive = !ifAbsent || !ifPresent;
164        Lock lock2 = exclusive ? lock.writeLock() : lock.readLock();
165        try {
166            lock2.lock();
167            // get the previous if used.
168            V prev = exclusive || isTransactional() ? map.get(key) : null;
169            if (prev == null && !ifAbsent)
170                return null;
171            if (prev != null && !ifPresent)
172                return null;
173            if (isTransactional()) {
174                Map<String, Map> mapOfKeys = new HashMap<String, Map>();
175                Map<K, V> map2 = new HashMap<K, V>();
176                map2.put(key, value);
177                mapOfKeys.put(getName(), map2);
178                include(changeCallback, mapOfKeys, null);
179                return prev;
180            }
181 
182            put0(key, value);
183            return prev;
184        } finally {
185            lock2.unlock();
186        }
187    }
188 
189    @Nullable protected V doRemove(@NotNull K key, boolean byValue, @Nullable V value) {
190        checkWrite();
191        try {
192            checkKey(key);
193            if (byValue)
194                checkValue(value);
195        } catch (IllegalArgumentException ignored) {
196            return null;
197        }
198 
199        Lock lock2 = byValue ? lock.writeLock() : lock.readLock();
200        try {
201            lock2.lock();
202 
203            V prev = byValue || isTransactional() ? map.get(key) : null;
204            if (byValue && !equals2(prev, value))
205                return null;
206            if (isTransactional()) {
207                Map<String, Map> mapOfKeys = new HashMap<String, Map>();
208                Map<K, V> map2 = new HashMap<K, V>();
209                map2.put((K) key, null);
210                mapOfKeys.put(name, map2);
211                include(changeCallback, mapOfKeys, null);
212                return prev;
213            }
214 
215            return remove(key);
216        } catch (Exception e) {
217            throw new IllegalStateException(e);
218        } finally {
219            lock2.unlock();
220        }
221    }
222 
223    protected void put0(K key, V value) {
224        V prev = map.put(key, value);
225        if (queue != null && prev == null)
226            queue.add(key);
227        notifyUpdate(key, value);
228    }
229 
230    @Nullable private V remove(@NotNull Object key) {
231        Lock nonexclusiveLock = lock.readLock();
232        V value;
233        try {
234            nonexclusiveLock.lock();
235            if (queue != null) queue.remove(key);
236            value = map.remove(key);
237        } finally {
238            nonexclusiveLock.unlock();
239        }
240        notifyUpdate((K) key, null);
241        return value;
242    }
243 
244    @Nullable protected V removeFirst() {
245        Lock exclusiveLock = lock.writeLock();
246        try {
247            exclusiveLock.lock();
248            if (map.isEmpty())
249                return null;
250            K key = queue == null ? map.keySet().iterator().next() : queue.first();
251            return remove(key);
252        } finally {
253            exclusiveLock.unlock();
254        }
255    }
256 
257    @NotNull protected Collection<V> values() {
258        Lock exclusiveLock = lock.writeLock();
259        try {
260            exclusiveLock.lock();
261            return map.values();
262        } finally {
263            exclusiveLock.unlock();
264        }
265    }
266 
267    @NotNull protected Collection<V> orderedValues() {
268        List<V> ret = new ArrayList<V>();
269        Lock exclusiveLock = lock.writeLock();
270        try {
271            exclusiveLock.lock();
272            if (queue == null)
273                return map.values();
274            for(K key: queue)
275                ret.add(map.get(key));
276            return ret;
277        } finally {
278            exclusiveLock.unlock();
279        }
280    }
281 
282    @Nullable public <R> R visit(@NotNull Visitor<Store<K, V>, R> visitor) throws VisitorException {
283        Transaction t = Transaction.start("visit MemoryStore");
284        Lock exclusiveLock = lock.writeLock();
285        try {
286            exclusiveLock.lock();
287            R r = visitor.visit(this);
288            t.commit();
289            return r;
290        } finally {
291            t.complete();
292            exclusiveLock.unlock();
293        }
294    }
295}

[all classes][org.jtoolkit.essence.data.impl]
EMMA 2.0.5312 (C) Vladimir Roubtsov