fix 🐛 available cache percents callback

This commit is contained in:
Alexey Danilov
2015-09-28 11:31:02 +06:00
parent e135bf0b42
commit 6125478d27
8 changed files with 65 additions and 23 deletions

View File

@@ -43,9 +43,6 @@ class HttpProxyCache extends ProxyCache {
}
out.write(buffer, 0, readBytes);
offset += readBytes;
if (cache.isCompleted()) {
onCacheAvailable(100);
}
}
out.flush();
}
@@ -68,7 +65,7 @@ class HttpProxyCache extends ProxyCache {
}
@Override
protected void onCacheAvailable(int percents) {
protected void onCachePercentsAvailableChanged(int percents) {
if (listener != null) {
listener.onCacheAvailable(cache.file, source.url, percents);
}

View File

@@ -24,9 +24,10 @@ class ProxyCache {
private final Cache cache;
private final Object wc = new Object();
private final Object stopLock = new Object();
private final AtomicInteger readSourceErrorsCount;
private volatile Thread sourceReaderThread;
private volatile boolean stopped;
private final AtomicInteger readSourceErrorsCount;
private volatile int percentsAvailable = -1;
public ProxyCache(Source source, Cache cache) {
this.source = checkNotNull(source);
@@ -42,7 +43,12 @@ class ProxyCache {
waitForSourceData();
checkReadSourceErrorsCount();
}
return cache.read(buffer, offset, length);
int read = cache.read(buffer, offset, length);
if (cache.isCompleted() && percentsAvailable != 100) {
percentsAvailable = 100;
onCachePercentsAvailableChanged(100);
}
return read;
}
private void checkReadSourceErrorsCount() throws ProxyCacheException {
@@ -86,22 +92,34 @@ class ProxyCache {
}
}
private void notifyNewCacheDataAvailable(int cachePercentage) {
onCacheAvailable(cachePercentage);
private void notifyNewCacheDataAvailable(long cacheAvailable, long sourceAvailable) {
onCacheAvailable(cacheAvailable, sourceAvailable);
synchronized (wc) {
wc.notifyAll();
}
}
protected void onCacheAvailable(int percents) {
protected void onCacheAvailable(long cacheAvailable, long sourceAvailable) {
int percents = (int) (cacheAvailable * 100 / sourceAvailable);
boolean percentsChanged = percents != percentsAvailable;
boolean sourceLengthKnown = sourceAvailable >= 0;
if (sourceLengthKnown && percentsChanged) {
onCachePercentsAvailableChanged(percents);
}
percentsAvailable = percents;
}
protected void onCachePercentsAvailableChanged(int percentsAvailable) {
}
private void readSource() {
int cachePercentage = 0;
int sourceAvailable = -1;
int offset = 0;
try {
int offset = cache.available();
offset = cache.available();
source.open(offset);
sourceAvailable = source.available();
byte[] buffer = new byte[ProxyCacheUtils.DEFAULT_BUFFER_SIZE];
int readBytes;
while ((readBytes = source.read(buffer)) != -1) {
@@ -112,9 +130,7 @@ class ProxyCache {
cache.append(buffer, readBytes);
}
offset += readBytes;
cachePercentage = offset * 100 / source.available();
notifyNewCacheDataAvailable(cachePercentage);
notifyNewCacheDataAvailable(offset, sourceAvailable);
}
tryComplete();
} catch (Throwable e) {
@@ -122,7 +138,7 @@ class ProxyCache {
onError(e);
} finally {
closeSource();
notifyNewCacheDataAvailable(cachePercentage);
notifyNewCacheDataAvailable(offset, sourceAvailable);
}
}

View File

@@ -7,11 +7,34 @@ package com.danikula.videocache;
*/
public interface Source {
int available() throws ProxyCacheException;
/**
* Opens source. Source should be open before using {@link #read(byte[])}
*
* @param offset offset in bytes for source.
* @throws ProxyCacheException if error occur while opening source.
*/
void open(int offset) throws ProxyCacheException;
void close() throws ProxyCacheException;
/**
* Returns available bytes or <b>negative value</b> if available bytes count is unknown.
*
* @return bytes available
* @throws ProxyCacheException if error occur while fetching source data.
*/
int available() throws ProxyCacheException;
/**
* Read data to byte buffer from source with current offset.
*
* @param buffer a buffer to be used for reading data.
* @throws ProxyCacheException if error occur while reading source.
*/
int read(byte[] buffer) throws ProxyCacheException;
/**
* Closes source and release resources. Every opened source should be closed.
*
* @throws ProxyCacheException if error occur while closing source.
*/
void close() throws ProxyCacheException;
}