From 4384ef5b738d4c1ecc039fa05127641f4b9ad6ef Mon Sep 17 00:00:00 2001 From: olly Date: Thu, 21 May 2020 12:00:56 +0100 Subject: [PATCH] Make CacheUtil only about writing A subsequent change will rename it to CacheWriter and make it instantiable. Issue: #5978 PiperOrigin-RevId: 312648623 --- .../exoplayer2/offline/SegmentDownloader.java | 19 +++-- .../exoplayer2/upstream/cache/CacheUtil.java | 69 ++++--------------- .../upstream/cache/CacheUtilTest.java | 60 ---------------- 3 files changed, 25 insertions(+), 123 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java index 3358cc02c84..02337248e15 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java @@ -18,7 +18,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import android.net.Uri; -import android.util.Pair; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.MediaItem; @@ -30,6 +29,7 @@ import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory; import com.google.android.exoplayer2.upstream.cache.CacheUtil; +import com.google.android.exoplayer2.upstream.cache.ContentMetadata; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.PriorityTaskManager; import com.google.android.exoplayer2.util.Util; @@ -136,11 +136,18 @@ public final void download(@Nullable ProgressListener progressListener) throws I long contentLength = 0; long bytesDownloaded = 0; for (int i = segments.size() - 1; i >= 0; i--) { - Segment segment = segments.get(i); - Pair segmentLengthAndBytesDownloaded = - CacheUtil.getCached(segment.dataSpec, cache, cacheKeyFactory); - long segmentLength = segmentLengthAndBytesDownloaded.first; - long segmentBytesDownloaded = segmentLengthAndBytesDownloaded.second; + DataSpec dataSpec = segments.get(i).dataSpec; + String cacheKey = cacheKeyFactory.buildCacheKey(dataSpec); + long segmentLength = dataSpec.length; + if (segmentLength == C.LENGTH_UNSET) { + long resourceLength = + ContentMetadata.getContentLength(cache.getContentMetadata(cacheKey)); + if (resourceLength != C.LENGTH_UNSET) { + segmentLength = resourceLength - dataSpec.position; + } + } + long segmentBytesDownloaded = + cache.getCachedBytes(cacheKey, dataSpec.position, segmentLength); bytesDownloaded += segmentBytesDownloaded; if (segmentLength != C.LENGTH_UNSET) { if (segmentLength == segmentBytesDownloaded) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java index 57c9ecbf558..1e850df278c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java @@ -15,7 +15,6 @@ */ package com.google.android.exoplayer2.upstream.cache; -import android.util.Pair; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import com.google.android.exoplayer2.C; @@ -57,38 +56,6 @@ public interface ProgressListener { @Deprecated public static final CacheKeyFactory DEFAULT_CACHE_KEY_FACTORY = CacheKeyFactory.DEFAULT; - /** - * Queries the cache to obtain the request length and the number of bytes already cached for a - * given {@link DataSpec}. - * - * @param dataSpec Defines the data to be checked. - * @param cache A {@link Cache} which has the data. - * @param cacheKeyFactory An optional factory for cache keys. - * @return A pair containing the request length and the number of bytes that are already cached. - */ - public static Pair getCached( - DataSpec dataSpec, Cache cache, @Nullable CacheKeyFactory cacheKeyFactory) { - String key = buildCacheKey(dataSpec, cacheKeyFactory); - long position = dataSpec.position; - long requestLength = getRequestLength(dataSpec, cache, key); - long bytesAlreadyCached = 0; - long bytesLeft = requestLength; - while (bytesLeft != 0) { - long blockLength = cache.getCachedLength(key, position, bytesLeft); - if (blockLength > 0) { - bytesAlreadyCached += blockLength; - } else { - blockLength = -blockLength; - if (blockLength == Long.MAX_VALUE) { - break; - } - } - position += blockLength; - bytesLeft -= bytesLeft == C.LENGTH_UNSET ? 0 : blockLength; - } - return Pair.create(requestLength, bytesAlreadyCached); - } - /** * Caches the data defined by {@code dataSpec}, skipping already cached data. Caching stops early * if the end of the input is reached. @@ -157,23 +124,26 @@ public static void cache( Assertions.checkNotNull(temporaryBuffer); Cache cache = dataSource.getCache(); - CacheKeyFactory cacheKeyFactory = dataSource.getCacheKeyFactory(); - String key = buildCacheKey(dataSpec, cacheKeyFactory); - long bytesLeft; + String cacheKey = dataSource.getCacheKeyFactory().buildCacheKey(dataSpec); + long requestLength = dataSpec.length; + if (requestLength == C.LENGTH_UNSET) { + long resourceLength = ContentMetadata.getContentLength(cache.getContentMetadata(cacheKey)); + if (resourceLength != C.LENGTH_UNSET) { + requestLength = resourceLength - dataSpec.position; + } + } + long bytesCached = cache.getCachedBytes(cacheKey, dataSpec.position, requestLength); @Nullable ProgressNotifier progressNotifier = null; if (progressListener != null) { progressNotifier = new ProgressNotifier(progressListener); - Pair lengthAndBytesAlreadyCached = getCached(dataSpec, cache, cacheKeyFactory); - progressNotifier.init(lengthAndBytesAlreadyCached.first, lengthAndBytesAlreadyCached.second); - bytesLeft = lengthAndBytesAlreadyCached.first; - } else { - bytesLeft = getRequestLength(dataSpec, cache, key); + progressNotifier.init(requestLength, bytesCached); } long position = dataSpec.position; + long bytesLeft = requestLength; while (bytesLeft != 0) { throwExceptionIfCanceled(isCanceled); - long blockLength = cache.getCachedLength(key, position, bytesLeft); + long blockLength = cache.getCachedLength(cacheKey, position, bytesLeft); if (blockLength > 0) { // Skip already cached data. } else { @@ -206,15 +176,6 @@ public static void cache( } } - private static long getRequestLength(DataSpec dataSpec, Cache cache, String key) { - if (dataSpec.length != C.LENGTH_UNSET) { - return dataSpec.length; - } else { - long contentLength = ContentMetadata.getContentLength(cache.getContentMetadata(key)); - return contentLength == C.LENGTH_UNSET ? C.LENGTH_UNSET : contentLength - dataSpec.position; - } - } - /** * Reads and discards all data specified by the {@code dataSpec}. * @@ -309,12 +270,6 @@ private static long readAndDiscard( } } - private static String buildCacheKey( - DataSpec dataSpec, @Nullable CacheKeyFactory cacheKeyFactory) { - return (cacheKeyFactory != null ? cacheKeyFactory : CacheKeyFactory.DEFAULT) - .buildCacheKey(dataSpec); - } - private static void throwExceptionIfCanceled(@Nullable AtomicBoolean isCanceled) throws InterruptedIOException { if (isCanceled != null && isCanceled.get()) { diff --git a/library/core/src/test/java/com/google/android/exoplayer2/upstream/cache/CacheUtilTest.java b/library/core/src/test/java/com/google/android/exoplayer2/upstream/cache/CacheUtilTest.java index eba664648b6..cc7a232b3f5 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/upstream/cache/CacheUtilTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/upstream/cache/CacheUtilTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.fail; import android.net.Uri; -import android.util.Pair; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; @@ -104,65 +103,6 @@ public void tearDown() { Util.recursiveDelete(tempFolder); } - @Test - public void getCachedNoData() { - Pair contentLengthAndBytesCached = - CacheUtil.getCached( - new DataSpec(Uri.parse("test")), mockCache, /* cacheKeyFactory= */ null); - - assertThat(contentLengthAndBytesCached.first).isEqualTo(C.LENGTH_UNSET); - assertThat(contentLengthAndBytesCached.second).isEqualTo(0); - } - - @Test - public void getCachedDataUnknownLength() { - // Mock there is 100 bytes cached at the beginning - mockCache.spansAndGaps = new int[] {100}; - Pair contentLengthAndBytesCached = - CacheUtil.getCached( - new DataSpec(Uri.parse("test")), mockCache, /* cacheKeyFactory= */ null); - - assertThat(contentLengthAndBytesCached.first).isEqualTo(C.LENGTH_UNSET); - assertThat(contentLengthAndBytesCached.second).isEqualTo(100); - } - - @Test - public void getCachedNoDataKnownLength() { - mockCache.contentLength = 1000; - Pair contentLengthAndBytesCached = - CacheUtil.getCached( - new DataSpec(Uri.parse("test")), mockCache, /* cacheKeyFactory= */ null); - - assertThat(contentLengthAndBytesCached.first).isEqualTo(1000); - assertThat(contentLengthAndBytesCached.second).isEqualTo(0); - } - - @Test - public void getCached() { - mockCache.contentLength = 1000; - mockCache.spansAndGaps = new int[] {100, 100, 200}; - Pair contentLengthAndBytesCached = - CacheUtil.getCached( - new DataSpec(Uri.parse("test")), mockCache, /* cacheKeyFactory= */ null); - - assertThat(contentLengthAndBytesCached.first).isEqualTo(1000); - assertThat(contentLengthAndBytesCached.second).isEqualTo(300); - } - - @Test - public void getCachedFromNonZeroPosition() { - mockCache.contentLength = 1000; - mockCache.spansAndGaps = new int[] {100, 100, 200}; - Pair contentLengthAndBytesCached = - CacheUtil.getCached( - new DataSpec(Uri.parse("test"), /* position= */ 100, /* length= */ C.LENGTH_UNSET), - mockCache, - /* cacheKeyFactory= */ null); - - assertThat(contentLengthAndBytesCached.first).isEqualTo(900); - assertThat(contentLengthAndBytesCached.second).isEqualTo(200); - } - @Test public void cache() throws Exception { FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100);