Path: blob/master/src/java.base/share/classes/sun/nio/cs/ThreadLocalCoders.java
41159 views
/*1* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/242526package sun.nio.cs;2728import java.nio.charset.*;293031/**32* Utility class for caching per-thread decoders and encoders.33*/3435public class ThreadLocalCoders {3637private static final int CACHE_SIZE = 3;3839private abstract static class Cache {4041// Thread-local reference to array of cached objects, in LRU order42private ThreadLocal<Object[]> cache = new ThreadLocal<>();43private final int size;4445Cache(int size) {46this.size = size;47}4849abstract Object create(Object name);5051private void moveToFront(Object[] oa, int i) {52Object ob = oa[i];53for (int j = i; j > 0; j--)54oa[j] = oa[j - 1];55oa[0] = ob;56}5758abstract boolean hasName(Object ob, Object name);5960Object forName(Object name) {61Object[] oa = cache.get();62if (oa == null) {63oa = new Object[size];64cache.set(oa);65} else {66for (int i = 0; i < oa.length; i++) {67Object ob = oa[i];68if (ob == null)69continue;70if (hasName(ob, name)) {71if (i > 0)72moveToFront(oa, i);73return ob;74}75}76}7778// Create a new object79Object ob = create(name);80oa[oa.length - 1] = ob;81moveToFront(oa, oa.length - 1);82return ob;83}8485}8687private static Cache decoderCache = new Cache(CACHE_SIZE) {88boolean hasName(Object ob, Object name) {89if (name instanceof Charset)90return ((CharsetDecoder)ob).charset().equals(name);91if (name instanceof String)92return (((CharsetDecoder)ob).charset().name().equals(name));93return false;94}95Object create(Object name) {96if (name instanceof Charset)97return ((Charset)name).newDecoder();98if (name instanceof String)99return Charset.forName((String)name).newDecoder();100assert false;101return null;102}103};104105public static CharsetDecoder decoderFor(Object name) {106CharsetDecoder cd = (CharsetDecoder)decoderCache.forName(name);107cd.reset();108return cd;109}110111private static Cache encoderCache = new Cache(CACHE_SIZE) {112boolean hasName(Object ob, Object name) {113if (name instanceof Charset)114return ((CharsetEncoder)ob).charset().equals(name);115if (name instanceof String)116return (((CharsetEncoder)ob).charset().name().equals(name));117return false;118}119Object create(Object name) {120if (name instanceof Charset)121return ((Charset)name).newEncoder();122if (name instanceof String)123return Charset.forName((String)name).newEncoder();124assert false;125return null;126}127};128129public static CharsetEncoder encoderFor(Object name) {130CharsetEncoder ce = (CharsetEncoder)encoderCache.forName(name);131ce.reset();132return ce;133}134135}136137138