Skip to content

Package: ThreadCache$ObjectCacheElement

ThreadCache$ObjectCacheElement

nameinstructionbranchcomplexitylinemethod
ThreadCache.ObjectCacheElement(int)
M: 10 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
get()
M: 15 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
put(Object)
M: 20 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
take()
M: 25 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.glassfish.grizzly;
18:
19: import java.util.Arrays;
20: import java.util.HashMap;
21: import java.util.Map;
22:
23: import org.glassfish.grizzly.threadpool.DefaultWorkerThread;
24:
25: /**
26: *
27: * @author oleksiys
28: */
29: public final class ThreadCache {
30: private static final ObjectCacheElement[] INITIAL_OBJECT_ARRAY = new ObjectCacheElement[16];
31:
32: private static final Map<String, CachedTypeIndex> typeIndexMap = new HashMap<>();
33:
34: private static int indexCounter;
35:
36: private static final ThreadLocal<ObjectCache> genericCacheAttr = new ThreadLocal<>();
37:
38: public static synchronized <E> CachedTypeIndex<E> obtainIndex(Class<E> clazz, int size) {
39: return obtainIndex(clazz.getName(), clazz, size);
40:
41: }
42:
43: @SuppressWarnings("unchecked")
44: public static synchronized <E> CachedTypeIndex<E> obtainIndex(String name, Class<E> clazz, int size) {
45:
46: CachedTypeIndex<E> typeIndex = typeIndexMap.get(name);
47: if (typeIndex == null) {
48: typeIndex = new CachedTypeIndex<>(indexCounter++, name, clazz, size);
49: typeIndexMap.put(name, typeIndex);
50: }
51:
52: return typeIndex;
53: }
54:
55: public static <E> boolean putToCache(final CachedTypeIndex<E> index, final E o) {
56: return putToCache(Thread.currentThread(), index, o);
57: }
58:
59: public static <E> boolean putToCache(final Thread currentThread, final CachedTypeIndex<E> index, final E o) {
60: if (currentThread instanceof DefaultWorkerThread) {
61: return ((DefaultWorkerThread) currentThread).putToCache(index, o);
62: } else {
63: ObjectCache genericCache = genericCacheAttr.get();
64: if (genericCache == null) {
65: genericCache = new ObjectCache();
66: genericCacheAttr.set(genericCache);
67: }
68:
69: return genericCache.put(index, o);
70: }
71: }
72:
73: /**
74: * Get the cached object with the given type index from cache. Unlike
75: * {@link #takeFromCache(org.glassfish.grizzly.ThreadCache.CachedTypeIndex)}, the object won't be removed from cache.
76: *
77: * @param <E> cached object type
78: * @param index the cached object type index.
79: * @return cached object.
80: */
81: public static <E> E getFromCache(final CachedTypeIndex<E> index) {
82: return getFromCache(Thread.currentThread(), index);
83: }
84:
85: /**
86: * Get the cached object with the given type index from cache. Unlike
87: * {@link #takeFromCache(org.glassfish.grizzly.ThreadCache.CachedTypeIndex)}, the object won't be removed from cache.
88: *
89: * @param <E> cached object type
90: * @param currentThread current {@link Thread}
91: * @param index the cached object type index.
92: * @return cached object.
93: */
94: public static <E> E getFromCache(final Thread currentThread, final CachedTypeIndex<E> index) {
95: assert currentThread == Thread.currentThread();
96:
97: if (currentThread instanceof DefaultWorkerThread) {
98: return ((DefaultWorkerThread) currentThread).getFromCache(index);
99: } else {
100: final ObjectCache genericCache = genericCacheAttr.get();
101: if (genericCache != null) {
102: return genericCache.get(index);
103: }
104:
105: return null;
106: }
107: }
108:
109: /**
110: * Take the cached object with the given type index from cache. Unlike
111: * {@link #getFromCache(org.glassfish.grizzly.ThreadCache.CachedTypeIndex)}, the object will be removed from cache.
112: *
113: * @param <E> cached object type
114: * @param index the cached object type index
115: * @return cached object
116: */
117: public static <E> E takeFromCache(final CachedTypeIndex<E> index) {
118: return takeFromCache(Thread.currentThread(), index);
119: }
120:
121: /**
122: * Take the cached object with the given type index from cache. Unlike
123: * {@link #getFromCache(org.glassfish.grizzly.ThreadCache.CachedTypeIndex)}, the object will be removed from cache.
124: *
125: * @param <E> cached object type
126: * @param currentThread current {@link Thread}
127: * @param index the cached object type index
128: * @return cached object
129: */
130: public static <E> E takeFromCache(final Thread currentThread, final CachedTypeIndex<E> index) {
131: if (currentThread instanceof DefaultWorkerThread) {
132: return ((DefaultWorkerThread) currentThread).takeFromCache(index);
133: } else {
134: final ObjectCache genericCache = genericCacheAttr.get();
135: if (genericCache != null) {
136: return genericCache.take(index);
137: }
138:
139: return null;
140: }
141: }
142:
143: public static final class ObjectCache {
144: private ObjectCacheElement[] objectCacheElements;
145:
146: public boolean put(final CachedTypeIndex index, final Object o) {
147: if (objectCacheElements != null && index.getIndex() < objectCacheElements.length) {
148: ObjectCacheElement objectCache = objectCacheElements[index.getIndex()];
149: if (objectCache == null) {
150: objectCache = new ObjectCacheElement(index.size);
151: objectCacheElements[index.getIndex()] = objectCache;
152: }
153:
154: return objectCache.put(o);
155: }
156:
157: final ObjectCacheElement[] arrayToGrow = objectCacheElements != null ? objectCacheElements : INITIAL_OBJECT_ARRAY;
158: final int newSize = Math.max(index.getIndex() + 1, arrayToGrow.length * 3 / 2 + 1);
159:
160: objectCacheElements = Arrays.copyOf(arrayToGrow, newSize);
161:
162: final ObjectCacheElement objectCache = new ObjectCacheElement(index.getSize());
163: objectCacheElements[index.getIndex()] = objectCache;
164: return objectCache.put(o);
165: }
166:
167: /**
168: * Get the cached object with the given type index from cache. Unlike
169: * {@link #take(org.glassfish.grizzly.ThreadCache.CachedTypeIndex)}, the object won't be removed from cache.
170: *
171: * @param <E> cached object type
172: * @param index the cached object type index.
173: * @return cached object.
174: */
175: @SuppressWarnings("unchecked")
176: public <E> E get(final CachedTypeIndex<E> index) {
177: final int idx;
178: if (objectCacheElements != null && (idx = index.getIndex()) < objectCacheElements.length) {
179:
180: final ObjectCacheElement objectCache = objectCacheElements[idx];
181: if (objectCache == null) {
182: return null;
183: }
184:
185: return (E) objectCache.get();
186: }
187:
188: return null;
189: }
190:
191: /**
192: * Take the cached object with the given type index from cache. Unlike
193: * {@link #get(org.glassfish.grizzly.ThreadCache.CachedTypeIndex)}, the object will be removed from cache.
194: *
195: * @param <E> cached object type
196: * @param index the cached object type index.
197: * @return cached object.
198: */
199: @SuppressWarnings("unchecked")
200: public <E> E take(final CachedTypeIndex<E> index) {
201: final int idx;
202: if (objectCacheElements != null && (idx = index.getIndex()) < objectCacheElements.length) {
203:
204: final ObjectCacheElement objectCache = objectCacheElements[idx];
205: if (objectCache == null) {
206: return null;
207: }
208:
209: return (E) objectCache.take();
210: }
211:
212: return null;
213: }
214: }
215:
216: public static final class ObjectCacheElement {
217: private final int size;
218: private final Object[] cache;
219: private int index;
220:
221: public ObjectCacheElement(int size) {
222: this.size = size;
223: cache = new Object[size];
224: }
225:
226: public boolean put(Object o) {
227:• if (index < size) {
228: cache[index++] = o;
229: return true;
230: }
231:
232: return false;
233: }
234:
235: /**
236: * Get (peek) the object from cache. Unlike {@link #take()} the object will not be removed from cache.
237: *
238: * @return object from cache.
239: */
240: public Object get() {
241:• if (index > 0) {
242: final Object o = cache[index - 1];
243: return o;
244: }
245:
246: return null;
247: }
248:
249: /**
250: * Take (poll) the object from cache. Unlike {@link #get()} the object will be removed from cache.
251: *
252: * @return object from cache.
253: */
254: public Object take() {
255:• if (index > 0) {
256: index--;
257:
258: final Object o = cache[index];
259: cache[index] = null;
260: return o;
261: }
262:
263: return null;
264: }
265: }
266:
267: public static final class CachedTypeIndex<E> {
268: private final int index;
269: private final Class clazz;
270: private final int size;
271: private final String name;
272:
273: public CachedTypeIndex(final int index, final String name, final Class<E> clazz, final int size) {
274: this.index = index;
275: this.name = name;
276: this.clazz = clazz;
277: this.size = size;
278: }
279:
280: public int getIndex() {
281: return index;
282: }
283:
284: public String getName() {
285: return name;
286: }
287:
288: public Class getClazz() {
289: return clazz;
290: }
291:
292: public int getSize() {
293: return size;
294: }
295: }
296: }