// Commented for the Learning branch package com.limegroup.bittorrent; import com.limegroup.gnutella.BandwidthTracker; /** * A SimpleBandwidthTracker object measures the speed of data flow. * It keeps 2 speeds: the speed right now, and the total average speed. * * Here's how to use a SimpleBandwidthTracker. * First, make one, s. * Regularly and repeatedly, call s.measureBandwidth(). * This will keep its current speed up to date. * When you transfer some data, call s.count(n) to tell it how many bytes you transferred right now. * To get the current speed, call speed = s.getMeasuredBandwidth(). * To get the total average speed, call speed = s.getAverageBandwidth(). * * Here's how SimpleBandwidthTracker works. * It keeps a current speed, _measuredBandwidth. * It has an internal interval, _interval, set by default at 3 seconds. * When you call measureBandwidth(), it only does something if the speed is older than 3 seconds. * If _measuredBandwidth is stale, it computes it again using just the most recent 3 seconds of data. * * This class implements the BandwidthTracker interface. * BandwidthTracker requires the methods measureBandwidth(), getMeasuredBandwidth(), and getAverageBandwidth(). */ public class SimpleBandwidthTracker implements BandwidthTracker { /** 3 seconds in milliseconds, by default, a SimpleBandwidthTracker will use at least 3 seconds of data to calculate its bandwidth. */ private static final int DEFAULT_INTERVAL = 3 * 1000; /** Compute the current speed from the bytes we've transferred in the last _interval milliseconds. */ private final int _interval; /** The total amount of distance we covered when we last computed the current speed. */ private volatile long _lastAmount = 0; /** The time when we last computed the current speed. */ private volatile long _lastTimeMeasured = 0; /** The time when we first computed our speed. */ private volatile long _firstTimeMeasured = 0; /** The total amount of distance we've covered, in bytes. */ private volatile long _amount = 0; /** The speed, in KB/s, that we most recently computed from at least _interval milliseconds of recent data. */ private volatile float _measuredBandwidth = 0.f; /** * Make a new SimpleBandwidthTracker object that can record how fast we're transferring data. * The BTUploader, BTDownloader, and BTMessageReader constructors make new SimpleBandwidthTracker objects for themselves, and save them as _tracker. */ public SimpleBandwidthTracker() { // Call the next constructor, passing the default of 3 seconds this(DEFAULT_INTERVAL); // This new SimpleBandwidthTracker will use the distance covered in the last 3 seconds to compute its current speed } /** * Make a new SimpleBandwidthTracker object that can record how fast we're transferring data. * Only the constructor above calls this one. * * @param interval Compute the current speed from the bytes we've transferred in the last _interval milliseconds */ public SimpleBandwidthTracker(int interval) { // Save the given interval _interval = interval; } /** * Have this SimpleBandwidthTracker object record that we just transferred some more bytes right now. * * @param added The number of bytes we just downloaded or uploaded */ public void count(int added) { // Add the given size to our total from the start _amount += added; } /** * Find out how much data transferred this SimpleBandwidthTracker object has recorded from its start. * * @return The total distance in bytes */ public long getTotalAmount() { // Return the total amount of data count() has added return _amount; } /** * Have this SimpleBandwidthTracker object update the speed it keeps current. * * When you make a SimpleBandwidthTracker object, call this measureBandwidth() method on it repeatedly. * Once every 3 seconds, it will use data from the last 3 seconds to calculate the current speed. * To find out what the speed is, call getMeasuredBandwidth(). */ public void measureBandwidth() { // Get the time now, the number of milliseconds since 1970 long now = System.currentTimeMillis(); // If this is the first time measureBandwidth() is running on a new SimpleBandwidthTracker object if (_firstTimeMeasured == 0) { // Set the first and most recent times to now _lastTimeMeasured = _firstTimeMeasured = now; return; } // If we haven't waited long enough yet, leave if (now - _lastTimeMeasured < _interval) return; // The caller will call measureBandwidth() again when we have enough new data /* * If control reaches here, we've waited at least 3 seconds since the last time. */ // Compute our current speed using data from the last 3 seconds or longer _measuredBandwidth = 1.f * (_amount - _lastAmount) / (now - _lastTimeMeasured); // Save the current distance and time for the next time we do this _lastAmount = _amount; _lastTimeMeasured = now; } /** * Get the current speed this SimpleBandwidthTracker has calculated. * Every 3 seconds, this SimpleBandwidthTracker calculates its current speed from the data it downloaded in the most recent 3 seconds. * This method returns that speed. * * @return The current speed, in KB/s. * 0.0 if not known or just started. */ public float getMeasuredBandwidth() { // Return the bandwidth measureBandwidth() calculated from the last 3 seconds of data return _measuredBandwidth; } /** * Get the total average bandwidth this SimpleBandwidthTracker object has recorded, from the very start of its record keeping. * Computes the average speed by dividing the total distance by the total time. * * @return The total average speed, in KB/s. */ public float getAverageBandwidth() { // Compute the speed from the total distance and total time return 1.f * _amount / (System.currentTimeMillis() - _firstTimeMeasured); } }