/* This code is part of Freenet. It is distributed under the GNU General * Public License, version 2 (or at your option any later version). See * http://www.gnu.org/ for further details of the GPL. */ package freenet.node; import freenet.support.LogThresholdCallback; import freenet.support.Logger; import freenet.support.SimpleFieldSet; import freenet.support.Logger.LogLevel; public class ThrottleWindowManager { private static volatile boolean logMINOR; static { Logger.registerLogThresholdCallback(new LogThresholdCallback() { @Override public void shouldUpdate() { logMINOR = Logger.shouldLog(LogLevel.MINOR, this); } }); } static final float PACKET_DROP_DECREASE_MULTIPLE = 0.97f; static final float PACKET_TRANSMIT_INCREMENT = (4 * (1 - (PACKET_DROP_DECREASE_MULTIPLE * PACKET_DROP_DECREASE_MULTIPLE))) / 3; private long _totalPackets = 0, _droppedPackets = 0; private double _simulatedWindowSize = 2; private final Node node; public ThrottleWindowManager(double def, SimpleFieldSet fs, Node node) { this.node = node; if(fs != null) { _totalPackets = fs.getInt("TotalPackets", 0); _droppedPackets = fs.getInt("DroppedPackets", 0); _simulatedWindowSize = fs.getDouble("SimulatedWindowSize", def); } else { _simulatedWindowSize = def; } } public synchronized double currentValue(boolean realTime) { if (_simulatedWindowSize < 1.0) { _simulatedWindowSize = 1.0F; } return _simulatedWindowSize * Math.max(1, node.peers.countNonBackedOffPeers(realTime)); } public synchronized void rejectedOverload() { _droppedPackets++; _totalPackets++; _simulatedWindowSize *= PACKET_DROP_DECREASE_MULTIPLE; if(logMINOR) Logger.minor(this, "request rejected overload: "+this); } public synchronized void requestCompleted() { _totalPackets++; _simulatedWindowSize += (PACKET_TRANSMIT_INCREMENT / _simulatedWindowSize); if(logMINOR) Logger.minor(this, "requestCompleted on "+this); } @Override public synchronized String toString() { return super.toString()+" w: " + _simulatedWindowSize + ", d:" + (((float) _droppedPackets / (float) _totalPackets)) + '=' +_droppedPackets+ '/' +_totalPackets; } public SimpleFieldSet exportFieldSet(boolean shortLived) { SimpleFieldSet fs = new SimpleFieldSet(shortLived); fs.putSingle("Type", "ThrottleWindowManager"); fs.put("TotalPackets", _totalPackets); fs.put("DroppedPackets", _droppedPackets); fs.put("SimulatedWindowSize", _simulatedWindowSize); return fs; } public double realCurrentValue() { return _simulatedWindowSize; } }