/*
* This file is part of Fim - File Integrity Manager
*
* Copyright (C) 2017 Etienne Vrignaud
*
* Fim 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.
*
* Fim 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 Fim. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fim.internal.hash;
import static java.lang.Math.max;
import static org.fim.model.Constants._1_MB;
public class ThroughputKeeper {
public static final int BLOCK_SIZE = 500 * _1_MB;
public static final int HALF_BLOCK_SIZE = BLOCK_SIZE / 2;
// Maintain a sliding window to compute throughput
private Position blockBegin;
private Position halfBlock;
public ThroughputKeeper() {
reset();
}
private void reset() {
this.blockBegin = new Position(0);
this.halfBlock = null;
}
public void update(long size) {
blockBegin.incSize(size);
if (halfBlock != null) {
halfBlock.incSize(size);
} else if (blockBegin.getSize() > HALF_BLOCK_SIZE) {
halfBlock = new Position(0);
}
if (blockBegin.getSize() > BLOCK_SIZE) {
blockBegin = halfBlock;
halfBlock = null;
}
}
public long getInstantThroughput() {
long durationMillis = blockBegin.getDurationMillis();
long durationSeconds;
long size = blockBegin.getSize();
if (durationMillis < 1_000) {
durationSeconds = 1;
size = (blockBegin.getSize() * 1_000) / durationMillis;
} else {
durationSeconds = durationMillis / 1_000;
}
return size / durationSeconds;
}
private static class Position {
private long size;
private long time;
public Position(long size) {
this.size = size;
this.time = System.currentTimeMillis();
}
public long getDurationMillis() {
return max(System.currentTimeMillis() - getTime(), 1);
}
public long getSize() {
return size;
}
public long getTime() {
return time;
}
public void incSize(long size) {
this.size += size;
}
}
}