Path: blob/master/test/functional/cmdLineTests/shareClassTests/DataHelperTests/src/CustomClassloaders/DataCachingClassLoader.java
6005 views
/*******************************************************************************1* Copyright (c) 2001, 2018 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/21package CustomClassloaders;2223import java.io.BufferedInputStream;24import java.io.IOException;25import java.io.InputStream;26import java.net.URL;27import java.net.URLClassLoader;28import java.nio.ByteBuffer;29import java.io.ByteArrayOutputStream;3031import com.ibm.oti.shared.Shared;32import com.ibm.oti.shared.SharedDataHelper;33import com.ibm.oti.shared.SharedDataHelperFactory;3435/**36* Uses the shared cache to store some resource data. In this implementation the getResourceAsStream() method37* is wired to use the shared cache.38*/39public class DataCachingClassLoader extends URLClassLoader {4041private static final boolean debug = true; // ==true means logging messages come out as this loader executes4243// Classloader users can check the counters, reset them with 'resetCounters()'44public int cacheStatsFindCount; /* Number of times we have called findSharedData() */45public int cacheStatsStoreCount; /* Number of times we have called storeSharedData() */46public int cacheStatsCacheHitCount; /* Number of times we have successfully found the data in the cache on findSharedData() */47public int cacheStatsCacheMissCount; /* Number of times we have not found the data in the cache on findSharedData() */4849// Control whether the cache should be used50public boolean storeInCache = true;51public boolean findInCache = true;5253private SharedDataHelper sdHelper;5455// ---5657public DataCachingClassLoader(URL[] urls, ClassLoader parent) {58super(urls, parent);59SharedDataHelperFactory helperFactory = Shared.getSharedDataHelperFactory();60if (helperFactory==null) throw new RuntimeException("No SharedDataHelperFactory found, are you running -Xshareclasses?");61sdHelper = (helperFactory==null?null:helperFactory.getDataHelper(this));62resetCounters();63}6465@Override66public InputStream getResourceAsStream(String name) {67if (findInCache && sdHelper!=null) {68ByteBuffer bBuffer = sdHelper.findSharedData(name);69if (bBuffer!=null) {70log("Returning an entry found in the cache");71return newInputStream(bBuffer);72}73}74InputStream realResource = super.getResourceAsStream(name);75if (realResource!=null && storeInCache && sdHelper!=null) {76log("Caching the data with token '"+name+"'");77BufferedInputStream bis = new BufferedInputStream(realResource);78ByteArrayOutputStream baos = new ByteArrayOutputStream();79byte[] data = new byte[256];80int readBytes = -1;81try {82while ( (readBytes=bis.read(data))!=-1) {83baos.write(data,0,readBytes);84}85} catch (IOException e) {86e.printStackTrace();87}88byte[] dataBytes = baos.toByteArray();89ByteBuffer bBuffer = ByteBuffer.allocateDirect(dataBytes.length);90bBuffer.put(dataBytes);91bBuffer = sdHelper.storeSharedData(name, bBuffer);92if (bBuffer==null) throw new RuntimeException("storeSharedData('"+name+"',...) has failed!");93return newInputStream(bBuffer);94} else {95return realResource;96}9798}99100101/** Return an InputStream that wraps a ByteBuffer */102public static InputStream newInputStream(final ByteBuffer buf) {103return new InputStream() {104public synchronized int read() throws IOException {105if (!buf.hasRemaining()) {106return -1;107}108return buf.get();109}110111public synchronized int read(byte[] bytes, int off, int len) throws IOException {112if (!buf.hasRemaining()) {113return -1;114}115// Read only what's left116len = Math.min(len, buf.remaining());117buf.get(bytes, off, len);118return len;119}120};121}122123public void resetCounters() {124cacheStatsCacheHitCount = 0;125cacheStatsCacheMissCount = 0;126cacheStatsFindCount = 0;127cacheStatsStoreCount = 0;128}129130// -- operations that work directly on the cache131132public InputStream findInCache(String token) {133if (sdHelper!=null) {134ByteBuffer bBuffer = sdHelper.findSharedData(token);135if (bBuffer!=null) return newInputStream(bBuffer);136}137return null;138}139140public void markStale(String token) {141if (sdHelper!=null) {142sdHelper.storeSharedData(token, null);143}144}145146// --- helpers147private void log(String msg) {148if (debug) System.out.println("DataCachingClassLoader: "+msg);149}150151public void storeNull(String token) {152if (sdHelper!=null) {153sdHelper.storeSharedData(token, null);154}155}156157public boolean forceStore(String token,String data) {158byte[] dataBytes = data.getBytes();159ByteBuffer bBuffer = ByteBuffer.allocateDirect(dataBytes.length);160bBuffer.put(dataBytes);161bBuffer = sdHelper.storeSharedData(token, bBuffer);162return (bBuffer!=null);163}164}165166167