net.sf.zig_project.gpl.common.io
Class ThreadedTransfer

java.lang.Object
  extended byjava.io.OutputStream
      extended bynet.sf.zig_project.gpl.common.io.ThreadedTransfer

public class ThreadedTransfer
extends OutputStream

The ThreadedTransfer class delegates IO operations to independant threads. This may result in a significant reduction in time required for a transfer to complete, as IO operations are scheduled concurrently, if possible.

The ideal use for this class is to transfer data from an InputStream to an OutputStream where the speed of each stream is roughly comparable to that of it's counterpart. Further, this class is also ideal for mirroring data across several OutputStreams, as this will attempt to mirror concurrently, instead of sequentially.

Each instance of ThreadedTransfer maintains a single shared buffer. Blocking will only occur when either the buffer is full, or enforce the ordering of writes to that buffer.

Notice: Every instance of this class must either be aborted or closed! Otherwise, active threads will continue to wait for further input data, and resources will neither be garbage collected nor finalized.

Version:
September 19, 2004
Author:
Frank Ziglar

Field Summary
static byte ABORTED
           
static byte CLOSED
           
 int frame_size
           
static byte OPEN
           
 ThreadGroup threads
          The threads object represents a control over the internal threads spawned by addOutput and addInput.
 
Constructor Summary
ThreadedTransfer(String desc)
           
ThreadedTransfer(String desc, int frame_sz)
           
ThreadedTransfer(String desc, int frame_len, int frame_count)
           
 
Method Summary
 void abort()
          Aborts the current ThreadedTransfer.
 void addOutput(OutputStream out, IOExceptionHandler eh)
          Adds out to the set of OutputStreams to which write and slurp operations will be mirrored.
 void close()
          Forces all previously added streams to close.
 void destroy()
          Ensures that this Transfer is safely terminated.
 void flush()
          Forces all output sources to perform a flush operation.
 byte getState()
          Allows polling of the state of the Transfer.
 void slurp(InputStream in)
          Uses the currently executing thread to load data from the selected InputStream and load it into the buffers for the OutputStream set.
 void write(byte[] buf, int off, int len)
          Writes data to all underlying OutputStreams.
 void write(int i)
          Writes a single byte of data to all underlying OutputStreams.
 
Methods inherited from class java.io.OutputStream
write
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

frame_size

public final int frame_size

threads

public final ThreadGroup threads
The threads object represents a control over the internal threads spawned by addOutput and addInput. It is provided to allow fine tuning control and debugging information. However, it should not be used to modify the state of those threads, or to parent new threads, as some calls methods will make calls to this group to notify those threads of a change in state.

Use with caution.


OPEN

public static final byte OPEN
See Also:
Constant Field Values

ABORTED

public static final byte ABORTED
See Also:
Constant Field Values

CLOSED

public static final byte CLOSED
See Also:
Constant Field Values
Constructor Detail

ThreadedTransfer

public ThreadedTransfer(String desc)

ThreadedTransfer

public ThreadedTransfer(String desc,
                        int frame_sz)

ThreadedTransfer

public ThreadedTransfer(String desc,
                        int frame_len,
                        int frame_count)
Method Detail

slurp

public void slurp(InputStream in)
           throws IOException
Uses the currently executing thread to load data from the selected InputStream and load it into the buffers for the OutputStream set. The contract of InputStream.read(byte[]), allows a return of 0 bytes. However this method will instead treat this behavior as an error, and throw an IOException in order to prevent having a potential infinite loop. Instead, implementations are expected to block until some data is available. Like Transfer.transfer(InputStream, OutputStream) since the provided InputStream is read to exhaustion, it is automatically closed before this method returns.

Throws:
IOException

addOutput

public void addOutput(OutputStream out,
                      IOExceptionHandler eh)
Adds out to the set of OutputStreams to which write and slurp operations will be mirrored. While other output streams may still be actively writing at the time of invocation, only data written to the transfer class after this stream has been added will be put into this stream. (ie: it is not necessary to call flush() before calling this method).


flush

public void flush()
           throws IOException
Forces all output sources to perform a flush operation. Typically, this method will wait for all streams to completely flush themselves, which should occur concurrently. If the current thread is interrupted while waiting for a stream to flush, no guarantees can be made that the stream recieved the flush event.

Throws:
InterruptedIOException - if the current thread was interrupted while waiting for all streams to flush
IOException - if the stream was not open when this call was made

close

public void close()
           throws InterruptedIOException
Forces all previously added streams to close. This method will attempt to wait for each output stream to be closed, however, unlike flush, even if the thread is interrupted, all output streams will independantly close down after a call to this method.

Throws:
InterruptedIOException - if the current thread was interrupted while waiting for all streams to close

getState

public byte getState()
Allows polling of the state of the Transfer. The state is either OPEN, ABORTED, or CLOSED. Calls to this method will never block, and may be made (safely) by any thread.

Returns:
the current state of the queue

write

public void write(byte[] buf,
                  int off,
                  int len)
           throws IOException
Writes data to all underlying OutputStreams. This method copies data from the provided buffer to the internal one where each individual OutputStream may access it and write it. Since copying the buffer is considered a negligable time requirement compared to IO, this method ignores the frame size, and attempts to perform the copy in as few operations as possible.

Throws:
InterruptedIOException - if the current thread was interrupted while waiting for more room in the internal buffer
IOException - if no OutputStreams are currently active in this transfer

write

public void write(int i)
           throws IOException
Writes a single byte of data to all underlying OutputStreams.

Throws:
InterruptedIOException - if the current thread was interrupted while waiting for room in the buffer to become available
IOException - if no OutputStreams are currently active in this transfer

abort

public void abort()
Aborts the current ThreadedTransfer. All active IO processes will either complete activation, or more likely, throw InterruptedIOExceptions. Their respective IOExceptionHandlers are responsible for making sure the stream is properly disposed of. Calls to this method may be made by any thread at any time, and never block.


destroy

public void destroy()
Ensures that this Transfer is safely terminated. If the current transfer has not yet been closed or aborted, this will force the transfer to abort. This method should be placed within a finally clause to ensure the instance has met some end and can be recollected.