public class RateLimitInputStream extends InputStream implements RateShaper
InputStream with a limited rate of bytes.
A stream has two blocking modes: blocking and non-blocking. If the stream is
in non-blocking mode, any call that would cause the stream to block (ie. all
read calls when no data is available) throw a WouldBlockException.
A stream has two boring modes: boring and non-boring. The boring flag
modifies he behavior of read(byte[], int, int) and
read(byte[]).
According to InputStream, they method read between 1 and n bytes,
where n is the size of the effective buffer.
If the RateLimitInputStream is in boring mode, the methods block
until all actually available bytes have been read, even if many ticks must be
waited for the data to become available according to the set rate.
In non-boring mode, the methods do not block and read only data which can be
read immediately (except for the first byte which, according to the
definition of InputStream, causes blocking for all read methods).
Note that blocking and boring are two different concept even though they seem
similar. Non-blocking will cause methods to throw exceptions, where
non-boring only means that read methods exit sooner in certain situations
than in boring mode.
Streams are non-boring by default.| Constructor and Description |
|---|
RateLimitInputStream(InputStream real,
TickSource tickSource,
int byteRate,
int prescale)
Constructs a byte-rate-limited
InputStream. |
| Modifier and Type | Method and Description |
|---|---|
int |
available()
This method complies with
InputStream.available() and imposes
stronger postconditions. |
void |
close() |
InputStream |
getBaseStream()
Returns the underlying
InputStream. |
int |
getByteRate()
Returns the bytes per tick (after prescaling) for this rate shaper.
|
int |
getPrescale()
Returns the current prescale value (ie.
|
TickSource |
getTickSource()
Returns the
TickSource this stream uses. |
void |
mark(int readlimit) |
boolean |
markSupported() |
int |
read()
Reads one byte from the stream.
|
int |
read(byte[] b)
Behaves the same as:
|
int |
read(byte[] b,
int off,
int len)
This method complies with
InputStream.read(byte[], int, int) and
imposes stronger postconditions. |
void |
reset() |
void |
setBoring(boolean boring)
Sets the boring flag.
|
void |
setByteRate(int bytesPerTick)
Sets a new byte rate per tick (after prescaling) for this rate shaper.
|
void |
setNonBlocking(boolean nonBlocking)
Sets the non-blocking flag.
|
void |
setPrescale(int prescale)
Sets a new prescale value (ie.
|
skippublic RateLimitInputStream(InputStream real, TickSource tickSource, int byteRate, int prescale)
InputStream.
The rate is given using two numbers: bytes per tick, and a prescale.
The prescale divides the incoming ticks by a constant number. A prescale
of 1 means that each tick coming from the tick source is counting towards
the rate, a prescale of 2 means every second, and so on. The prescale can
be used to achieve low byte rates, ie. rates below 1 byte per tick.
For example, a rate of 1 byte per tick and a prescale of 4 means that one
byte is read after 4 ticks coming from the tick source.real - The actual InputStream to read fromtickSource - The tick sourcebyteRate - The rate, ie. the limit of how many bytes per tick (after
prescaling) should be readable from this streamprescale - The prescaling, ie. the frequency of ticks to actually consider
for rating.public void setByteRate(int bytesPerTick)
RateShapersetByteRate in interface RateShaperbytesPerTick - the new byte rate per tick (after prescaling)public int getByteRate()
RateShapergetByteRate in interface RateShaperpublic int read()
throws IOException
InputStream or a rate block has been
encountered, regardless of the stream's boring flag.read in class InputStreamIOExceptionpublic int read(byte[] b,
int off,
int len)
throws IOException
InputStream.read(byte[], int, int) and
imposes stronger postconditions.
Reads up to len bytes from the stream. This method blocks for
the first byte reagrdless of the stream's boring flag. For all subsequent
bytes, the behavior depends on the boring flag:
InputStream.available()) have been read, even if this means
waiting for the next tick.InputStream.read(byte[], int, int).read in class InputStreamIOExceptionpublic int read(byte[] b)
throws IOException
read(b, 0, b.length);
read in class InputStreamIOExceptionpublic int available()
throws IOException
InputStream.available() and imposes
stronger postconditions.
The returned value is the number of bytes available for immediate reading.
If there is no rate limitation in place (ie. the rate has not been reached
for the current tick), the InputStream.available() method of the
underlying InputStream is called. If a rate limitation is in
place, the number of bytes readable in the current tick is returned.available in class InputStreamIOExceptionpublic void close()
throws IOException
close in interface Closeableclose in interface AutoCloseableclose in class InputStreamIOExceptionpublic void mark(int readlimit)
mark in class InputStreampublic boolean markSupported()
markSupported in class InputStreampublic void reset()
throws IOException
reset in class InputStreamIOExceptionpublic void setBoring(boolean boring)
boring - whether the stream should be in boring mode (see
RateLimitInputStream(InputStream, TickSource, int, int)
).public void setNonBlocking(boolean nonBlocking)
nonBlocking - whether the stream should be in non-blocking mode (see
RateLimitInputStream).public InputStream getBaseStream()
InputStream.public TickSource getTickSource()
TickSource this stream uses.public int getPrescale()
RateShapergetPrescale in interface RateShaperpublic void setPrescale(int prescale)
RateShapersetPrescale in interface RateShaperprescale - the new prescaleCopyright © 2015. All rights reserved.