/* * MediathekView * Copyright (C) 2013 W. Xaver * W.Xaver[at]googlemail.com * http://zdfmediathk.sourceforge.net/ * * org.apache.hadoop.tools.util.ThrottledInputStream * unter http://www.apache.org/licenses/LICENSE-2.0 * diente als Vorlage * * 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 * 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 mediathek.controller; import mediathek.daten.DatenDownload; import mediathek.tool.MVFilmSize; import java.io.IOException; import java.io.InputStream; import java.util.TimerTask; import java.util.concurrent.locks.ReentrantReadWriteLock; public class MVInputStream extends InputStream { private final InputStream iStream; private MVBandwidthTokenBucket bucket = null; private final BandwidthCalculationTask calculationTask; public MVInputStream(InputStream in, java.util.Timer calculationTimer) { iStream = in; bucket = new MVBandwidthTokenBucket(); bucket.ensureBucketThreadIsRunning(); //start bandwidth calculation calculationTask = new BandwidthCalculationTask(); calculationTimer.scheduleAtFixedRate(calculationTask, 0, 1000); } @Override public void close() throws IOException { iStream.close(); super.close(); //stop bandwidth calculation calculationTask.cancel(); } @Override public int read() throws IOException { bucket.takeBlocking(); final int bytesRead = iStream.read(); if (bytesRead != -1) { calculationTask.incrementBytesRead(1); } return bytesRead; } @Override public int read(byte[] b) throws IOException { bucket.takeBlocking(b.length); final int bytesRead = iStream.read(b); if (bytesRead != -1) { calculationTask.incrementBytesRead(bytesRead); } return bytesRead; } /** * Return the akt bandwidth used by this InputStream. * * @return akt Bandwidth in bytes per second. */ public long getBandwidth() { return calculationTask.getBandwidth(); } /** * Return the sum time used by this InputStream. * * @return time in second. */ public long getSumTime() { return calculationTask.getSumTime(); } public long getSumByte() { return calculationTask.getTotalBytesRead(); } /** * Return the bandwidth used by this InputStream. * * @return Bandwidth in bytes per second for the complete download. */ public long getSumBandwidth() { final long bytesRead = calculationTask.getTotalBytesRead(); final long time = calculationTask.getSumTime(); return bytesRead <= 0 ? 0 : bytesRead / time; } @Override public String toString() { final long bytesRead = calculationTask.getTotalBytesRead(); final long b = getSumBandwidth(); String s = MVFilmSize.humanReadableByteCount(bytesRead, true); return "Download: Bytes gelesen: " + s + " Bandbreite: " + DatenDownload.getTextBandbreite(b); } public String[] getMsg() { final long bytesRead = calculationTask.getTotalBytesRead(); final long b = getSumBandwidth(); String s = MVFilmSize.humanReadableByteCount(bytesRead, true); return new String[]{"Download", "Bytes gelesen: " + s, "Bandbreite: " + DatenDownload.getTextBandbreite(b)}; } /** * This TimerTask calculates the bandwidth (bytes per seconds) and records the overall bytes read * until termination. */ private class BandwidthCalculationTask extends TimerTask { private long oldTotalBytes = 0; private long totalBytesRead = 0; private long bandwidth = 0; private long sumTime = 0; private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); @Override public void run() { lock.writeLock().lock(); bandwidth = totalBytesRead - oldTotalBytes; oldTotalBytes = totalBytesRead; ++sumTime; lock.writeLock().unlock(); } public void incrementBytesRead(int value) { lock.writeLock().lock(); totalBytesRead += value; lock.writeLock().unlock(); } /** * Return the total number of bytes read. * * @return Total number of bytes read. */ public long getTotalBytesRead() { lock.readLock().lock(); final long res = totalBytesRead; lock.readLock().unlock(); return res; } /** * Return the bandwidth used by this stream. * * @return Bandwidth in bytes per second. */ public long getBandwidth() { lock.readLock().lock(); final long bw = bandwidth; lock.readLock().unlock(); return bw; } /** * Return the sum of time used by this stream. * * @return Time in s */ public long getSumTime() { lock.readLock().lock(); final long t = sumTime; lock.readLock().unlock(); return t; } } }