Class IntSeries

java.lang.Object
com.frostwire.jlibtorrent.IntSeries

public final class IntSeries extends Object
Circular buffer for storing time-series integer statistics.

IntSeries maintains a fixed-size circular buffer of data points, typically used to store equally-spaced time-series samples of session statistics. Once the buffer fills, new data overwrites the oldest data, maintaining a rolling window of recent samples.

Understanding Circular Buffers:
A circular buffer is a fixed-size array where write position wraps around to the start after reaching the end. This is efficient for maintaining a sliding window of data:

 // Example: 5-element buffer, adding values 1, 2, 3, 4, 5, 6
 // After adding: [6, 2, 3, 4, 5]
 //                ^
 //                write position wraps around
 

Creating an IntSeries:

 // Create series with capacity for 60 samples (e.g., 60 seconds of data)
 IntSeries series = new IntSeries(60);

 // Or create from existing buffer
 long[] buffer = new long[120];
 IntSeries series = new IntSeries(buffer);
 

Adding Data Points:

 IntSeries series = new IntSeries(60);

 // Add statistics samples (typically called once per second)
 for (int i = 0; i < 65; i++) {
     long downloadBytes = sm.stats().totalDownload();
     series.add(downloadBytes);

     if (i == 60) {
         // After 60 samples, oldest data starts getting overwritten
         System.out.println(\"Buffer size: \" + series.size());  // = 60
     }
 }
 

Querying Data:

 // Get most recent value
 long latest = series.last();

 // Get series size (how many samples stored)
 int samples = series.size();

 // Iterate through all samples (newest to oldest)
 for (int i = 0; i < series.size(); i++) {
     long value = series.get(i);
     System.out.println(\"Sample \" + i + \": \" + value);
 }
 

Practical Use Case - Download Speed Calculation:

 // Track download speed over 60 seconds
 IntSeries downloadSamples = new IntSeries(60);
 SessionManager sm = new SessionManager();
 sm.start();

 // Sample download bytes every second
 Timer timer = new Timer();
 timer.schedule(new TimerTask() {
     public void run() {
         SessionStats stats = sm.stats();
         long totalDownload = stats.totalDownload();
         downloadSamples.add(totalDownload);
     }
 }, 0, 1000);  // Every 1000ms

 // Calculate average speed over last minute
 long firstSample = downloadSamples.get(downloadSamples.size() - 1);
 long lastSample = downloadSamples.last();
 long deltaBytes = lastSample - firstSample;
 long deltaSeconds = downloadSamples.size();  // One second per sample
 long avgSpeed = deltaBytes / deltaSeconds;  // bytes per second
 

Buffer Behavior:

 // New series starts empty
 IntSeries series = new IntSeries(5);
 System.out.println(series.size());  // 0

 series.add(100);
 System.out.println(series.size());  // 1
 System.out.println(series.last());  // 100

 // Add more samples
 for (int i = 0; i < 10; i++) {
     series.add(100 + i);
 }

 // Buffer now full with 5 most recent samples
 System.out.println(series.size());  // 5
 System.out.println(series.last());  // 109 (most recent)
 System.out.println(series.get(4)); // 105 (oldest in buffer)
 

Index Wrapping:

 // Warning: Index wraps around buffer boundaries
 IntSeries series = new IntSeries(3);
 series.add(10);
 series.add(20);
 series.add(30);

 // series.get(0) = 10  (oldest)
 // series.get(1) = 20  (middle)
 // series.get(2) = 30  (newest/last)

 // Be careful! Accessing beyond size wraps around
 // series.get(series.size() - 1) returns last()
 // series.get(series.size()) may return wrappedindex values
 

Important Notes:

  • Buffer size is fixed at creation; no growth or shrinking
  • New series has size() = 0 until first value added
  • last() returns 0 if series empty or end pointer not set
  • Access beyond size() causes index wrapping (undefined behavior)
  • Always check size() before accessing; don't assume capacity
  • Used internally for sliding-window statistics

Performance Notes:

  • add(): O(1) - constant time operation
  • get(): O(1) - direct array access with modulo calculation
  • last(): O(1) - direct element access
  • Memory: Fixed by buffer capacity, no dynamic allocation
See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    long
    get(int index)
    This method will always returns a value, but keep in mind that due to the nature of the circular buffer internal logic, if you pass past the size, you will get the sames values again.
    long
    This method will always returns a value, if the series is empty 0 is returned.
    int
     
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Method Details

    • get

      public long get(int index)
      This method will always returns a value, but keep in mind that due to the nature of the circular buffer internal logic, if you pass past the size, you will get the sames values again. Use for a proper boundary check.

      Usage example:

       
           for (int i = min(series.size(), desired_count); i >= 0; i--) {
               plotMyValueAt(i, series.get(i));
           }
       
       
      Parameters:
      index - the value's index
      Returns:
      the value in the series
    • last

      public long last()
      This method will always returns a value, if the series is empty 0 is returned.
      Returns:
      the last value in the series
    • size

      public int size()
    • toString

      public String toString()
      Overrides:
      toString in class Object