/**
* A component of a library for
* GENESIS
* Copyright (C) 2008
* Andy Turner,
* University of Leeds.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
package uk.ac.leeds.ccg.andyt.projects.genesis.utilities;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
/**
* An abstract class
to be extended by classes that are required to
* handle runtime errors such as java.lang.OutOfMemroyError
.
*
HashMap
storing class.getName()
as keys
and
* the numbers of caches swapped of that class
as values
.
*/
private HashMap numberOfCachesSwappedAsFilesHashMap;
/**
* Reserve memory. This is to be cleared when dealing with OutOfMemoryErrors
.
*/
private transient int[] memoryReserve;
//public transient int[] memoryReserve;
/**
* Initialises this.memoryReserve
as an int[]
of length size.
* @param size The length that this.memoryReserve
is initialised as.
*/
public final void initMemoryReserve( int size ) {
//log( "initMemoryReserve( " + size + " )" );
this.memoryReserve = new int[ size ];
Arrays.fill( this.memoryReserve, Integer.MIN_VALUE );
System.gc();
}
/**
* Initialises memoryReserve as an array of size 3000000.
* Enough memory is needed for swapping data to this.directory
*/
public final void initMemoryReserve() {
initMemoryReserve( 3000000 );
}
/**
* Clears memoryReserve by setting it to null and calling the garbage
* collector.
*/
public final void clearMemoryReserve() {
//System.gc();
//log(Runtime.getRuntime().freeMemory());
this.memoryReserve = null;
System.gc();
//log(Runtime.getRuntime().freeMemory());
}
/**
* If aHashSetSerializable.isEmpty()
this does nothing and returns null.
* Otherwise aHashSetSerializable
is swapped to a File
* which is returned.
*/
protected File swapToFile(
HashSet _HashSet ) {
//throws IOException {
if ( _HashSet.isEmpty() ) {
return null;
} else {
String type = _HashSet.getClass().getName();
if ( true ) {
Iterator aHashSetSerializableIterator = _HashSet.iterator();
type += aHashSetSerializableIterator.next().getClass().getName();
}
int numberOfCachesSwappedAsFiles = ( Integer ) this.numberOfCachesSwappedAsFilesHashMap.get( type );
numberOfCachesSwappedAsFiles ++;
this.numberOfCachesSwappedAsFilesHashMap.put( type, numberOfCachesSwappedAsFiles );
File aFile = FileCreator.createNewFile(
this.directory,
type + Integer.toString( numberOfCachesSwappedAsFiles ) );
try {
ObjectOutputStream aObjectOutputStream = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream( aFile ) ) );
aObjectOutputStream.writeObject( _HashSet );
aObjectOutputStream.flush();
aObjectOutputStream.close();
} catch ( IOException aIOException ) {
aIOException.printStackTrace();
//throw ioe0;
}
return aFile;
}
}
/**
* If aHashMap.isEmpty()
this does nothing and returns null.
* Otherwise aHashMap
is swapped to a File
* which is returned.
*/
protected File swapToFile(
HashMap aHashMap ) {
//throws IOException {
if ( aHashMap.isEmpty() ) {
return null;
} else {
String type = aHashMap.getClass().getName();
if ( true ) {
Iterator aHashMapKeySetIterator = aHashMap.keySet().iterator();
type += aHashMapKeySetIterator.next().getClass().getName();
Iterator aHashMapValuesIterator = aHashMap.values().iterator();
type += aHashMapValuesIterator.next().getClass().getName();
}
int numberOfCachesSwappedAsFiles = ( Integer ) this.numberOfCachesSwappedAsFilesHashMap.get( type );
numberOfCachesSwappedAsFiles ++;
this.numberOfCachesSwappedAsFilesHashMap.put( type, numberOfCachesSwappedAsFiles );
File aFile = FileCreator.createNewFile(
this.directory,
type + Integer.toString( numberOfCachesSwappedAsFiles ) );
try {
ObjectOutputStream aObjectOutputStream = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream( aFile ) ) );
aObjectOutputStream.writeObject( aHashMap );
aObjectOutputStream.flush();
aObjectOutputStream.close();
} catch ( IOException aIOException ) {
aIOException.printStackTrace();
//throw ioe0;
}
return aFile;
}
}
/**
* A method to write this instance to Files located in this.directory.
* @param handleOutOfMemoryError
* If true then OutOfMemoryErrors are caught, swap operations are initiated,
* then the method is re-called.
* If false then OutOfMemoryErrors are caught and thrown.
*/
public final File writeToFile(
boolean handleOutOfMemoryError )
throws IOException {
try {
return writeToFile();
} catch ( OutOfMemoryError oome0 ) {
if ( handleOutOfMemoryError ) {
return writeToFile( handleOutOfMemoryError );
} else {
throw oome0;
}
}
}
/**
* A method to write this instance to a File located in the directory returned by
* getDirectory().
*/
protected File writeToFile() throws IOException {
// Write out this.
String filename = this.getClass().getName();
File file = new File(
getDirectory(),
filename + ".thisFile" );
//System.out.println("Writing out to " + file.toURL().toString() );
ObjectOutputStream aObjectOutputStream = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream( file ) ) );
aObjectOutputStream.writeObject( this );
aObjectOutputStream.flush();
aObjectOutputStream.close();
return file;
}
/**
* A method to write this instance to a File located in the directory returned by
* getDirectory().
* @param objectToWrite The object to be written
*/
protected void writeToFile(
Object objectToWrite,
File aFileToWriteTo )
throws IOException {
ObjectOutputStream aObjectOutputStream = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream( aFileToWriteTo ) ) );
aObjectOutputStream.writeObject( objectToWrite );
aObjectOutputStream.flush();
aObjectOutputStream.close();
}
/**
* Loads an Object
from aFile File
.
* @param aFile The File
from which the Object
ObjectnullObject from aObjectInputStream ObjectInputStream
.
* @param aObjectInputStream The ObjectInputStream
from which the Object
Objectnullthis.directory
*/
public final File getDirectory() {
return this.directory;
}
/**
* Sets this.directory
to directory
.
* N.B. No checks are done on directory
to ensure it is viable for use.
*/
protected final void setDirectory( File directory ) {
this.directory = directory;
}
/**
* @return this.memoryReserve
*/
protected final int[] getMemoryReserve() {
return this.memoryReserve;
}
/**
* Sets this.memoryReserve
to memoryReserve
.
*/
protected final void setMemoryReserve( int[] memoryReserve ) {
this.memoryReserve = memoryReserve;
}
/**
* @return this.numberOfCachesSwappedAsFilesHashMap
*/
protected final HashMap getNumberOfCachesSwappedAsFilesHashMap() {
return this.numberOfCachesSwappedAsFilesHashMap;
}
/**
* Sets this.numberOfCachesSwappedAsFilesHashMap
to numberOfCachesSwappedAsFilesHashMap
.
*/
protected final void setNumberOfCachesSwappedAsFilesHashMap( HashMap numberOfCachesSwappedAsFilesHashMap ) {
this.numberOfCachesSwappedAsFilesHashMap = numberOfCachesSwappedAsFilesHashMap;
}
}