/* * Copyright (C) 2014 Shashank Tulsyan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package neembuu.vfs.progresscontrol; /** * * @author Shashank Tulsyan */ final class SpeedObv { private volatile long offset = 0; private volatile long initialOffset = 0; private volatile long initialTime = 0; // non volatile because we assume that progressed is called from // one thread only private int i = 0; private final int l; private final long[]x; private final long[]t; private int to_skip = 0; private int skipped = 0; private int skip_change_wait_counter ; private volatile double speed_Bps = 0; private final int minimum_cycle_interval = 3000; private final int maximum_cycle_interval = 9000; public SpeedObv() {this(100,0);} public SpeedObv(int l, long offset) { this.l = l; x = new long[l]; t = new long[l]; reset(0); skip_change_wait_counter = l; } public void reset(){ reset(offset); } public void reset(long offset){ this.offset = offset; this.initialOffset = offset; initialTime = System.currentTimeMillis(); } public final int getL() { return l; } public final double getSpeed_Bps() { return speed_Bps; } public final double getSpeed_KiBps() { return speed_Bps/1024d; } public final double getSpeed_MiBps() { return speed_Bps/(1024d*1024d); } public void setThisAsInitialPointForAverage() { initialOffset = offset; initialTime = System.currentTimeMillis(); } public double getAverage_Bps(){ long a_dt = System.currentTimeMillis()-initialTime; long a_dx = ((offset - initialOffset)*1000); if(a_dt<0) System.out.println("dt<0"); if(a_dx<0) System.out.println("dx<0"); if(a_dt!=0) return a_dx / a_dt; return 0; } public double getAverage_KiBps(){ return getAverage_Bps()/1024; } public double getAverage_MiBps(){ return getAverage_Bps()/(1024*1024); } public void progressed(int dx){ offset += dx; if(to_skip!=0){ if(skipped%to_skip!=0){skipped++;return;} } skipped++; x[i%l] = offset; t[i%l] = System.currentTimeMillis(); double downloadSpeedEntry = 1; if(i<1){ downloadSpeedEntry = 1; } else if(i < l){ long dt = t[i]-t[0]; if(dt==0)dt=1; downloadSpeedEntry = (x[i] - x[0]) / dt ; }else { long dt = (t[i%l] - t[(i+1)%l]); downloadSpeedEntry = (x[i%l] - x[(i+1)%l]) / dt ; if(skip_change_wait_counter>0)skip_change_wait_counter--; if(dt < minimum_cycle_interval/*ms*/){ if(skip_change_wait_counter==0){ if(to_skip==0)to_skip=1; else to_skip*=2; //System.out.println("skip incr to = "+to_skip); skip_change_wait_counter = l; } }else if(dt > maximum_cycle_interval/*ms*/){ if(skip_change_wait_counter==0){ if(to_skip!=0){ if(to_skip==1)to_skip=0; else to_skip/=2; // System.out.println("skip dec to = "+to_skip); skip_change_wait_counter = l; } } } } speed_Bps = downloadSpeedEntry*1000; i++; } }