1 /*
2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
82 // update weak reference:
83 refBuckets = new WeakReference<Bucket[]>(buckets);
84 }
85 return buckets;
86 }
87
88 Reference createRef(final int initialSize) {
89 return new Reference(this, initialSize);
90 }
91
92 static final class Reference {
93
94 // initial array reference (direct access)
95 final byte[] initial;
96 private final boolean clean;
97 private final ByteArrayCache cache;
98
99 Reference(final ByteArrayCache cache, final int initialSize) {
100 this.cache = cache;
101 this.clean = cache.clean;
102 this.initial = createArray(initialSize, clean);
103 if (DO_STATS) {
104 cache.stats.totalInitial += initialSize;
105 }
106 }
107
108 byte[] getArray(final int length) {
109 if (length <= MAX_ARRAY_SIZE) {
110 return cache.getCacheBucket(length).getArray();
111 }
112 if (DO_STATS) {
113 cache.stats.oversize++;
114 }
115 if (DO_LOG_OVERSIZE) {
116 logInfo(getLogPrefix(clean) + "ByteArrayCache: "
117 + "getArray[oversize]: length=\t" + length);
118 }
119 return createArray(length, clean);
120 }
121
122 byte[] widenArray(final byte[] array, final int usedSize,
123 final int needSize)
124 {
125 final int length = array.length;
126 if (DO_CHECKS && length >= needSize) {
127 return array;
128 }
129 if (DO_STATS) {
130 cache.stats.resize++;
131 }
132
133 // maybe change bucket:
134 // ensure getNewSize() > newSize:
135 final byte[] res = getArray(ArrayCacheConst.getNewSize(usedSize, needSize));
136
137 // use wrapper to ensure proper copy:
138 System.arraycopy(array, 0, res, 0, usedSize); // copy only used elements
139
185 {
186 this.arraySize = arraySize;
187 this.clean = clean;
188 this.stats = stats;
189 this.arrays = new byte[capacity][];
190 }
191
192 byte[] getArray() {
193 if (DO_STATS) {
194 stats.getOp++;
195 }
196 // use cache:
197 if (tail != 0) {
198 final byte[] array = arrays[--tail];
199 arrays[tail] = null;
200 return array;
201 }
202 if (DO_STATS) {
203 stats.createOp++;
204 }
205 return createArray(arraySize, clean);
206 }
207
208 void putArray(final byte[] array)
209 {
210 if (DO_CHECKS && (array.length != arraySize)) {
211 logInfo(getLogPrefix(clean) + "ByteArrayCache: "
212 + "bad length = " + array.length);
213 return;
214 }
215 if (DO_STATS) {
216 stats.returnOp++;
217 }
218 // fill cache:
219 if (arrays.length > tail) {
220 arrays[tail++] = array;
221
222 if (DO_STATS) {
223 stats.updateMaxSize(tail);
224 }
225 } else if (DO_CHECKS) {
226 logInfo(getLogPrefix(clean) + "ByteArrayCache: "
227 + "array capacity exceeded !");
228 }
229 }
230 }
231
232 static byte[] createArray(final int length, final boolean clean) {
233 if (clean) {
234 return new byte[length];
235 }
236 // use JDK9 Unsafe.allocateUninitializedArray(class, length):
237 return (byte[]) OffHeapArray.UNSAFE.allocateUninitializedArray(byte.class, length);
238 }
239
240 static void fill(final byte[] array, final int fromIndex,
241 final int toIndex, final byte value)
242 {
243 // clear array data:
244 Arrays.fill(array, fromIndex, toIndex, value);
245 if (DO_CHECKS) {
246 check(array, fromIndex, toIndex, value);
247 }
248 }
249
250 static void check(final byte[] array, final int fromIndex,
251 final int toIndex, final byte value)
252 {
253 if (DO_CHECKS) {
254 // check zero on full array:
255 for (int i = 0; i < array.length; i++) {
256 if (array[i] != value) {
257 logException("Invalid value at: " + i + " = " + array[i]
|
1 /*
2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
82 // update weak reference:
83 refBuckets = new WeakReference<Bucket[]>(buckets);
84 }
85 return buckets;
86 }
87
88 Reference createRef(final int initialSize) {
89 return new Reference(this, initialSize);
90 }
91
92 static final class Reference {
93
94 // initial array reference (direct access)
95 final byte[] initial;
96 private final boolean clean;
97 private final ByteArrayCache cache;
98
99 Reference(final ByteArrayCache cache, final int initialSize) {
100 this.cache = cache;
101 this.clean = cache.clean;
102 this.initial = createArray(initialSize);
103 if (DO_STATS) {
104 cache.stats.totalInitial += initialSize;
105 }
106 }
107
108 byte[] getArray(final int length) {
109 if (length <= MAX_ARRAY_SIZE) {
110 return cache.getCacheBucket(length).getArray();
111 }
112 if (DO_STATS) {
113 cache.stats.oversize++;
114 }
115 if (DO_LOG_OVERSIZE) {
116 logInfo(getLogPrefix(clean) + "ByteArrayCache: "
117 + "getArray[oversize]: length=\t" + length);
118 }
119 return createArray(length);
120 }
121
122 byte[] widenArray(final byte[] array, final int usedSize,
123 final int needSize)
124 {
125 final int length = array.length;
126 if (DO_CHECKS && length >= needSize) {
127 return array;
128 }
129 if (DO_STATS) {
130 cache.stats.resize++;
131 }
132
133 // maybe change bucket:
134 // ensure getNewSize() > newSize:
135 final byte[] res = getArray(ArrayCacheConst.getNewSize(usedSize, needSize));
136
137 // use wrapper to ensure proper copy:
138 System.arraycopy(array, 0, res, 0, usedSize); // copy only used elements
139
185 {
186 this.arraySize = arraySize;
187 this.clean = clean;
188 this.stats = stats;
189 this.arrays = new byte[capacity][];
190 }
191
192 byte[] getArray() {
193 if (DO_STATS) {
194 stats.getOp++;
195 }
196 // use cache:
197 if (tail != 0) {
198 final byte[] array = arrays[--tail];
199 arrays[tail] = null;
200 return array;
201 }
202 if (DO_STATS) {
203 stats.createOp++;
204 }
205 return createArray(arraySize);
206 }
207
208 void putArray(final byte[] array)
209 {
210 if (DO_CHECKS && (array.length != arraySize)) {
211 logInfo(getLogPrefix(clean) + "ByteArrayCache: "
212 + "bad length = " + array.length);
213 return;
214 }
215 if (DO_STATS) {
216 stats.returnOp++;
217 }
218 // fill cache:
219 if (arrays.length > tail) {
220 arrays[tail++] = array;
221
222 if (DO_STATS) {
223 stats.updateMaxSize(tail);
224 }
225 } else if (DO_CHECKS) {
226 logInfo(getLogPrefix(clean) + "ByteArrayCache: "
227 + "array capacity exceeded !");
228 }
229 }
230 }
231
232 static byte[] createArray(final int length) {
233 return new byte[length];
234 }
235
236 static void fill(final byte[] array, final int fromIndex,
237 final int toIndex, final byte value)
238 {
239 // clear array data:
240 Arrays.fill(array, fromIndex, toIndex, value);
241 if (DO_CHECKS) {
242 check(array, fromIndex, toIndex, value);
243 }
244 }
245
246 static void check(final byte[] array, final int fromIndex,
247 final int toIndex, final byte value)
248 {
249 if (DO_CHECKS) {
250 // check zero on full array:
251 for (int i = 0; i < array.length; i++) {
252 if (array[i] != value) {
253 logException("Invalid value at: " + i + " = " + array[i]
|