org.klomp.snark

## Class BandwidthManager

- java.lang.Object
- - org.klomp.snark.BandwidthManager

- All Implemented Interfaces:
    BandwidthListener

      public class BandwidthManager
      extends Object
      implements BandwidthListener

  Bandwidth and bandwidth limits

  Maintain three bandwidth estimators: Sent, received, and requested.

  There are three layers of BandwidthListeners:

        BandwidthManager (total)
            PeerCoordinator (per-torrent)
                Peer/WebPeer (per-connection)

  Here at the top, we use SyntheticRedQueues for accurate and current moving averages of up, down, and requested bandwidth.

  At the lower layers, simple weighted moving averages of three buckets of time PeerCoordinator.CHECK_PERIOD each are used for up and down, and requested is delegated here.

  The lower layers must report to the next-higher layer.

  At the Peer layer, we report inbound piece data per-read, not per-piece, to get a smoother inbound estimate.

  Only the following data are counted by the BandwidthListeners:

  - Pieces (both Peer and WebPeer)
  - ut_metadata
  No overhead at any layer is accounted for.

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `BandwidthManager(I2PAppContext ctx, int upLimit, int downLimit)`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `downloaded(int size)` We received this many bytes
    `long` | `getDownBWLimit()` Current limit in BPS
    `long` | `getDownloadRate()` The average rate in Bps
    `(package private) long` | `getRequestRate()` The average rate in Bps
    `long` | `getUpBWLimit()` Current limit in BPS
    `long` | `getUploadRate()` The average rate in Bps
    `boolean` | `overDownBWLimit()` Are we currently over the limit?
    `boolean` | `overUpBWLimit()` Are we currently over the limit?
    `(package private) void` | `setDownBWLimit(long downLimit)` Current limit in Bps
    `(package private) void` | `setUpBWLimit(long upLimit)` Current limit in Bps
    `boolean` | `shouldRequest(Peer peer, int size)` Should we request this many bytes?
    `boolean` | `shouldSend(int size)` Should we send this many bytes? Do NOT call uploaded() if this returns true.
    `String` | `toString()` In HTML for debug page
    `void` | `uploaded(int size)` We unconditionally sent this many bytes

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Constructor Detail

    - #### BandwidthManager

          BandwidthManager(I2PAppContext ctx,
                           int upLimit,
                           int downLimit)

  - ### Method Detail

    - #### downloaded

          public void downloaded(int size)

      We received this many bytes
      Specified by:
        `downloaded` in interface `BandwidthListener`
      Parameters:
        `size` - the number of bytes received

    - #### getDownBWLimit

          public long getDownBWLimit()

      Current limit in BPS
      Specified by:
        `getDownBWLimit` in interface `BandwidthListener`
      Returns:
        the download limit in Bps

    - #### getDownloadRate

          public long getDownloadRate()

      The average rate in Bps
      Specified by:
        `getDownloadRate` in interface `BandwidthListener`
      Returns:
        the average download rate in Bps

    - #### getRequestRate

          long getRequestRate()

      The average rate in Bps

    - #### getUpBWLimit

          public long getUpBWLimit()

      Current limit in BPS
      Specified by:
        `getUpBWLimit` in interface `BandwidthListener`
      Returns:
        the upload limit in Bps

    - #### getUploadRate

          public long getUploadRate()

      The average rate in Bps
      Specified by:
        `getUploadRate` in interface `BandwidthListener`
      Returns:
        the average upload rate in Bps

    - #### overDownBWLimit

          public boolean overDownBWLimit()

      Are we currently over the limit?
      Specified by:
        `overDownBWLimit` in interface `BandwidthListener`
      Returns:
        true if over the download limit, false otherwise

    - #### overUpBWLimit

          public boolean overUpBWLimit()

      Are we currently over the limit?
      Specified by:
        `overUpBWLimit` in interface `BandwidthListener`
      Returns:
        true if over the upload limit, false otherwise

    - #### setDownBWLimit

          void setDownBWLimit(long downLimit)

      Current limit in Bps

    - #### setUpBWLimit

          void setUpBWLimit(long upLimit)

      Current limit in Bps

    - #### shouldRequest

          public boolean shouldRequest(Peer peer,
                                       int size)

      Should we request this many bytes?
      Specified by:
        `shouldRequest` in interface `BandwidthListener`
      Parameters:
        `peer` - ignored
        `size` - the number of bytes to request
      Returns:
        true if the request should be made, false otherwise

    - #### shouldSend

          public boolean shouldSend(int size)

      Should we send this many bytes? Do NOT call uploaded() if this returns true.
      Specified by:
        `shouldSend` in interface `BandwidthListener`
      Parameters:
        `size` - the number of bytes to send
      Returns:
        true if the bytes should be sent, false otherwise

    - #### toString

          public String toString()

      In HTML for debug page
      Overrides:
        `toString` in class `Object`

    - #### uploaded

          public void uploaded(int size)

      We unconditionally sent this many bytes
      Specified by:
        `uploaded` in interface `BandwidthListener`
      Parameters:
        `size` - the number of bytes sent