gausssoft.io
Class BandwidthControlledInputStream

java.lang.Object
  |
  +--java.io.InputStream
        |
        +--java.io.FilterInputStream
              |
              +--gausssoft.io.StatusInputStream
                    |
                    +--gausssoft.io.ChunkingInputStream
                          |
                          +--gausssoft.io.BandwidthInputStream
                                |
                                +--gausssoft.io.BandwidthControlledInputStream

public class BandwidthControlledInputStream
extends BandwidthInputStream

This class restricts the level of throughput that flows to an underlying InputStream.

This implementation uses the ChunkingInputStream class to perform updates. It is recommended that you look at how the ChunkingInputStream class works before using this class.

This class lets a certain amount of bytes pass to the underlying stream (which can be set at construction time and also by the ChunkingInputStream.setChunkSize(int) method). After this amount of bytes pass through the stream, it is calculated if bandwidth has been exceeded. If it has, the method will pause to average the bandwidth out.

The lower the chunk size, the more method overhead that will be generated, as well as any inefficiency by reading in data in small chunks. The higher the chunk size, the less method overhead, as well as being more efficient by reading in data in bigger chunks, however, this results in more of a burst-stop effect.

For example, if you have a very restrictive bandwidth on a stream which is very fast, and you set the chunk size to a very large size, initial reads will occur at the normal stream speed, disregarding the bandwidth limit. When a check is enforced, it will pause for a long while to average out the bandwidth. Although this "burst-stop" effect will happen whatever chunk size you specify, throughput will be much more consistent if it is set for lower values.

You can also specify if bandwidth restrictions should still apply at the end of the stream. For example, say you have a stream containing 2000 bytes, and you have a chunk size of 1500. An initial read of 1250 is performed, followed by 250 bytes (which will force a bandwidth check). You now have 500 bytes left. You attempt to read another 1000 bytes, but only 500 bytes are left, so 500 bytes are returned. This then leaves 500 bytes that have not been checked. You can specify whether these bytes should be subject to bandwidth checks as well.

Since:
GSDK 1.1
Author:
Allan Crooks
See Also:
BandwidthControlledOutputStream, BandwidthInputStream

Fields inherited from class java.io.FilterInputStream
in
 
Constructor Summary
BandwidthControlledInputStream(InputStream in, int bps)
          Creates a new BandwidthControlledInputStream using a chunk size of 1024 bytes that does not perform end of stream checks.
BandwidthControlledInputStream(InputStream in, int bps, int chunksize)
          Creates a new BandwidthControlledInputStream that does not perform end of stream checks.
BandwidthControlledInputStream(InputStream in, int bps, int chunksize, boolean end)
          Creates a new BandwidthControlledInputStream.
 
Method Summary
protected  void forceCheck()
          Forces any unchecked bytes that have passed to the underlying stream to be checked immediately (and for bandwidth to be averaged out).
 int getLimit()
          Returns the current bandwidth limit.
 void initiate()
          Begins measuring and restricting bandwidth to the underlying InputStream.
protected  void interrupt()
          Used for enforcing bandwidth checks.
 boolean isLimiting()
          Returns true if this object is restricting bandwidth.
 void setLimit(int bps)
          Sets a new bandwidth limit.
 void setLimiting(boolean active)
          Enables / disables the limiting of throughput on this object.
 
Methods inherited from class gausssoft.io.BandwidthInputStream
close, getBandwidth, initiated, resetMeasuring
 
Methods inherited from class gausssoft.io.ChunkingInputStream
getChunkSize, read, read, read, setChunkSize, skip, updateChunkSize
 
Methods inherited from class gausssoft.io.StatusInputStream
available, getCount, isClosed, isEmpty
 
Methods inherited from class java.io.FilterInputStream
mark, markSupported, reset
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

BandwidthControlledInputStream

public BandwidthControlledInputStream(InputStream in,
                                      int bps)
Creates a new BandwidthControlledInputStream using a chunk size of 1024 bytes that does not perform end of stream checks.
Parameters:
in - The InputStream to wrap around.
bps - The bandwidth to limit the stream to.
Throws:
NullPointerException - If in is null.
IllegalArgumentException - If bps is less than 1.

BandwidthControlledInputStream

public BandwidthControlledInputStream(InputStream in,
                                      int bps,
                                      int chunksize)
Creates a new BandwidthControlledInputStream that does not perform end of stream checks.
Parameters:
in - The InputStream to wrap around.
bps - The bandwidth to limit the stream to.
chunksize - The chunk size to use.
Throws:
NullPointerException - If in is null.
IllegalArgumentException - If bps or chunksize is less than 1.

BandwidthControlledInputStream

public BandwidthControlledInputStream(InputStream in,
                                      int bps,
                                      int chunksize,
                                      boolean end)
Creates a new BandwidthControlledInputStream.
Parameters:
in - The InputStream to wrap around.
bps - The bandwidth to limit the stream to.
chunksize - The chunk size to use.
end - true if bandwidth should still be adjusted at the end of a stream.
Throws:
NullPointerException - If in is null.
IllegalArgumentException - If bps or chunksize is less than 1.
Method Detail

initiate

public void initiate()
Begins measuring and restricting bandwidth to the underlying InputStream. This method is also overrideable by subclasses that need to be explicitly told to function properly instead of functioning immediately at construction time.
Overrides:
initiate in class BandwidthInputStream
See Also:
BandwidthInputStream.initiated()

isLimiting

public final boolean isLimiting()
Returns true if this object is restricting bandwidth.
Returns:
true if this object is restricting bandwidth.

setLimiting

public final void setLimiting(boolean active)
Enables / disables the limiting of throughput on this object.
Parameters:
active - true if this object should begin limiting throughput.

getLimit

public final int getLimit()
Returns the current bandwidth limit.
Returns:
The current bandwidth limit.

setLimit

public final void setLimit(int bps)
Sets a new bandwidth limit.
Parameters:
bps - The new bandwidth limit.
Throws:
IllegalArgumentException - If bps is less than 1.

interrupt

protected void interrupt()
Used for enforcing bandwidth checks.
Overrides:
interrupt in class BandwidthInputStream
See Also:
ChunkingInputStream.interrupt(), forceCheck()

forceCheck

protected final void forceCheck()
Forces any unchecked bytes that have passed to the underlying stream to be checked immediately (and for bandwidth to be averaged out).

Note: This method must be called only when no IO operations are currently taking place. Invoking this method will use the current bandwidth limit and activity setting. Any new values which have yet to be stored in the variables will not be used.

See Also:
interrupt()