001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 * Created on Oct 1, 2009 021 * Author: Andreas Prlic 022 * 023 */ 024 025package org.biojava.nbio.core.util; 026 027import org.slf4j.Logger; 028import org.slf4j.LoggerFactory; 029 030import java.io.*; 031 032/** 033 * Provides a cache for storing multiple small files in memory. Can be used to e.g cache gzip compressed PDB files 034 * for avoiding disk IO bottlenecks. 035 * Note this is just a wrapper for the singleton cache. 036 * 037 * @author Andreas Prlic. 038 * 039 */ 040public class FlatFileCache { 041 042 private final static Logger logger = LoggerFactory.getLogger(FlatFileCache.class); 043 044 /** 045 * The cache singleton. 046 */ 047 private static SoftHashMap<String, byte[]> cache = new SoftHashMap<String, byte[]>(0); 048 049 050 // no public constructor; 051 private FlatFileCache(){ 052 053 } 054 055 056 public static void addToCache(String key, File fileToCache){ 057 //logger.debug("storing " + key + " on file cache (cache size: " + cache.size() + ")"); 058 try { 059 InputStream is = new FileInputStream(fileToCache); 060 // Get the size of the file 061 long length = fileToCache.length(); 062 063 // You cannot create an array using a long type. 064 // It needs to be an int type. 065 // Before converting to an int type, check 066 // to ensure that file is not larger than Integer.MAX_VALUE. 067 if (length > Integer.MAX_VALUE) { 068 // File is too large 069 } 070 071 // Create the byte array to hold the data 072 byte[] bytes = new byte[(int)length]; 073 074 // Read in the bytes 075 int offset = 0; 076 int numRead = 0; 077 while (offset < bytes.length 078 && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { 079 offset += numRead; 080 } 081 082 // Ensure all the bytes have been read in 083 if (offset < bytes.length) { 084 is.close(); 085 throw new IOException("Could not completely read file "+fileToCache.getName()); 086 } 087 088 // Close the input stream and return bytes 089 is.close(); 090 091 cache.put(key,bytes); 092 093 } catch (Exception e){ 094 logger.error("Error adding to cache! " + e.getMessage(), e); 095 } 096 } 097 098 public static InputStream getInputStream(String key){ 099 //logger.debug("returning " + key + " from file cache (cache size: " + cache.size() + ")"); 100 byte[] bytes = cache.get(key); 101 if ( bytes == null) 102 return null; 103 104 return new ByteArrayInputStream(bytes); 105 106 } 107 108 public static int size() { 109 if ( cache != null) 110 return cache.size(); 111 else 112 return -1; 113 } 114 115 public static void clear(){ 116 cache.clear(); 117 } 118 119 120 121}