@@ -24,9 +24,10 @@ class ProxyCache {
2424 private final Cache cache ;
2525 private final Object wc = new Object ();
2626 private final Object stopLock = new Object ();
27+ private final AtomicInteger readSourceErrorsCount ;
2728 private volatile Thread sourceReaderThread ;
2829 private volatile boolean stopped ;
29- private final AtomicInteger readSourceErrorsCount ;
30+ private volatile int percentsAvailable = - 1 ;
3031
3132 public ProxyCache (Source source , Cache cache ) {
3233 this .source = checkNotNull (source );
@@ -42,7 +43,12 @@ public int read(byte[] buffer, long offset, int length) throws ProxyCacheExcepti
4243 waitForSourceData ();
4344 checkReadSourceErrorsCount ();
4445 }
45- return cache .read (buffer , offset , length );
46+ int read = cache .read (buffer , offset , length );
47+ if (cache .isCompleted () && percentsAvailable != 100 ) {
48+ percentsAvailable = 100 ;
49+ onCachePercentsAvailableChanged (100 );
50+ }
51+ return read ;
4652 }
4753
4854 private void checkReadSourceErrorsCount () throws ProxyCacheException {
@@ -86,22 +92,34 @@ private void waitForSourceData() throws ProxyCacheException {
8692 }
8793 }
8894
89- private void notifyNewCacheDataAvailable (int cachePercentage ) {
90- onCacheAvailable (cachePercentage );
95+ private void notifyNewCacheDataAvailable (long cacheAvailable , long sourceAvailable ) {
96+ onCacheAvailable (cacheAvailable , sourceAvailable );
9197
9298 synchronized (wc ) {
9399 wc .notifyAll ();
94100 }
95101 }
96102
97- protected void onCacheAvailable (int percents ) {
103+ protected void onCacheAvailable (long cacheAvailable , long sourceAvailable ) {
104+ int percents = (int ) (cacheAvailable * 100 / sourceAvailable );
105+ boolean percentsChanged = percents != percentsAvailable ;
106+ boolean sourceLengthKnown = sourceAvailable >= 0 ;
107+ if (sourceLengthKnown && percentsChanged ) {
108+ onCachePercentsAvailableChanged (percents );
109+ }
110+ percentsAvailable = percents ;
111+ }
112+
113+ protected void onCachePercentsAvailableChanged (int percentsAvailable ) {
98114 }
99115
100116 private void readSource () {
101- int cachePercentage = 0 ;
117+ int sourceAvailable = -1 ;
118+ int offset = 0 ;
102119 try {
103- int offset = cache .available ();
120+ offset = cache .available ();
104121 source .open (offset );
122+ sourceAvailable = source .available ();
105123 byte [] buffer = new byte [ProxyCacheUtils .DEFAULT_BUFFER_SIZE ];
106124 int readBytes ;
107125 while ((readBytes = source .read (buffer )) != -1 ) {
@@ -112,17 +130,15 @@ private void readSource() {
112130 cache .append (buffer , readBytes );
113131 }
114132 offset += readBytes ;
115- cachePercentage = offset * 100 / source .available ();
116-
117- notifyNewCacheDataAvailable (cachePercentage );
133+ notifyNewCacheDataAvailable (offset , sourceAvailable );
118134 }
119135 tryComplete ();
120136 } catch (Throwable e ) {
121137 readSourceErrorsCount .incrementAndGet ();
122138 onError (e );
123139 } finally {
124140 closeSource ();
125- notifyNewCacheDataAvailable (cachePercentage );
141+ notifyNewCacheDataAvailable (offset , sourceAvailable );
126142 }
127143 }
128144
0 commit comments