Commit 49eb27da by falhassen Committed by Oliver Woodman

Add a CacheKeyFactory to CacheDataSource.

A CacheKeyFactory can be passed to the CacheDataSource constructor, allowing clients to dynamically generate a custom cache key for any given upstream uri.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=198878723
parent 536bd682
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
### dev-v2 (not yet released) ### ### dev-v2 (not yet released) ###
* Allow apps to pass a `CacheKeyFactory` for setting custom cache keys when
creating a `CacheDataSource`.
* Turned on Java 8 compiler support for the ExoPlayer library. Apps that depend * Turned on Java 8 compiler support for the ExoPlayer library. Apps that depend
on ExoPlayer via its source code rather than an AAR may need to add on ExoPlayer via its source code rather than an AAR may need to add
`compileOptions { targetCompatibility JavaVersion.VERSION_1_8 }` to their `compileOptions { targetCompatibility JavaVersion.VERSION_1_8 }` to their
......
...@@ -119,6 +119,7 @@ public final class CacheDataSource implements DataSource { ...@@ -119,6 +119,7 @@ public final class CacheDataSource implements DataSource {
private final DataSource cacheReadDataSource; private final DataSource cacheReadDataSource;
private final DataSource cacheWriteDataSource; private final DataSource cacheWriteDataSource;
private final DataSource upstreamDataSource; private final DataSource upstreamDataSource;
private final CacheKeyFactory cacheKeyFactory;
@Nullable private final EventListener eventListener; @Nullable private final EventListener eventListener;
private final boolean blockOnCache; private final boolean blockOnCache;
...@@ -178,8 +179,13 @@ public final class CacheDataSource implements DataSource { ...@@ -178,8 +179,13 @@ public final class CacheDataSource implements DataSource {
*/ */
public CacheDataSource(Cache cache, DataSource upstream, @Flags int flags, public CacheDataSource(Cache cache, DataSource upstream, @Flags int flags,
long maxCacheFileSize) { long maxCacheFileSize) {
this(cache, upstream, new FileDataSource(), new CacheDataSink(cache, maxCacheFileSize), this(
flags, null); cache,
upstream,
new FileDataSource(),
new CacheDataSink(cache, maxCacheFileSize),
flags,
/* eventListener= */ null);
} }
/** /**
...@@ -198,8 +204,43 @@ public final class CacheDataSource implements DataSource { ...@@ -198,8 +204,43 @@ public final class CacheDataSource implements DataSource {
*/ */
public CacheDataSource(Cache cache, DataSource upstream, DataSource cacheReadDataSource, public CacheDataSource(Cache cache, DataSource upstream, DataSource cacheReadDataSource,
DataSink cacheWriteDataSink, @Flags int flags, @Nullable EventListener eventListener) { DataSink cacheWriteDataSink, @Flags int flags, @Nullable EventListener eventListener) {
this(
cache,
upstream,
cacheReadDataSource,
cacheWriteDataSink,
flags,
eventListener,
/* cacheKeyFactory= */ null);
}
/**
* Constructs an instance with arbitrary {@link DataSource} and {@link DataSink} instances for
* reading and writing the cache. One use of this constructor is to allow data to be transformed
* before it is written to disk.
*
* @param cache The cache.
* @param upstream A {@link DataSource} for reading data not in the cache.
* @param cacheReadDataSource A {@link DataSource} for reading data from the cache.
* @param cacheWriteDataSink A {@link DataSink} for writing data to the cache. If null, cache is
* accessed read-only.
* @param flags A combination of {@link #FLAG_BLOCK_ON_CACHE}, {@link #FLAG_IGNORE_CACHE_ON_ERROR}
* and {@link #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}, or 0.
* @param eventListener An optional {@link EventListener} to receive events.
* @param cacheKeyFactory An optional factory for cache keys.
*/
public CacheDataSource(
Cache cache,
DataSource upstream,
DataSource cacheReadDataSource,
DataSink cacheWriteDataSink,
@Flags int flags,
@Nullable EventListener eventListener,
@Nullable CacheKeyFactory cacheKeyFactory) {
this.cache = cache; this.cache = cache;
this.cacheReadDataSource = cacheReadDataSource; this.cacheReadDataSource = cacheReadDataSource;
this.cacheKeyFactory =
cacheKeyFactory != null ? cacheKeyFactory : CacheUtil.DEFAULT_CACHE_KEY_FACTORY;
this.blockOnCache = (flags & FLAG_BLOCK_ON_CACHE) != 0; this.blockOnCache = (flags & FLAG_BLOCK_ON_CACHE) != 0;
this.ignoreCacheOnError = (flags & FLAG_IGNORE_CACHE_ON_ERROR) != 0; this.ignoreCacheOnError = (flags & FLAG_IGNORE_CACHE_ON_ERROR) != 0;
this.ignoreCacheForUnsetLengthRequests = this.ignoreCacheForUnsetLengthRequests =
...@@ -216,7 +257,7 @@ public final class CacheDataSource implements DataSource { ...@@ -216,7 +257,7 @@ public final class CacheDataSource implements DataSource {
@Override @Override
public long open(DataSpec dataSpec) throws IOException { public long open(DataSpec dataSpec) throws IOException {
try { try {
key = CacheUtil.getKey(dataSpec); key = cacheKeyFactory.buildCacheKey(dataSpec);
uri = dataSpec.uri; uri = dataSpec.uri;
actualUri = getRedirectedUriOrDefault(cache, key, /* defaultUri= */ uri); actualUri = getRedirectedUriOrDefault(cache, key, /* defaultUri= */ uri);
flags = dataSpec.flags; flags = dataSpec.flags;
......
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.upstream.cache;
import android.net.Uri;
import com.google.android.exoplayer2.upstream.DataSpec;
/** Factory for custom cache keys. */
public interface CacheKeyFactory {
/**
* Returns a custom cache key for the given {@link Uri}.
*
* @param dataSpec The upstream source from which data will be read and cached.
*/
String buildCacheKey(DataSpec dataSpec);
}
...@@ -54,6 +54,15 @@ public final class CacheUtil { ...@@ -54,6 +54,15 @@ public final class CacheUtil {
/** Default buffer size to be used while caching. */ /** Default buffer size to be used while caching. */
public static final int DEFAULT_BUFFER_SIZE_BYTES = 128 * 1024; public static final int DEFAULT_BUFFER_SIZE_BYTES = 128 * 1024;
/** Default {@link CacheKeyFactory} that calls through to {@link #getKey}. */
public static final CacheKeyFactory DEFAULT_CACHE_KEY_FACTORY =
new CacheKeyFactory() {
@Override
public String buildCacheKey(DataSpec dataSpec) {
return getKey(dataSpec);
}
};
/** /**
* Generates a cache key out of the given {@link Uri}. * Generates a cache key out of the given {@link Uri}.
* *
......
...@@ -132,6 +132,22 @@ public final class CacheUtilTest { ...@@ -132,6 +132,22 @@ public final class CacheUtilTest {
} }
@Test @Test
public void testDefaultCacheKeyFactory_buildCacheKey() throws Exception {
Uri testUri = Uri.parse("test");
String key = "key";
// If DataSpec.key is present, returns it
assertThat(
CacheUtil.DEFAULT_CACHE_KEY_FACTORY.buildCacheKey(
new DataSpec(testUri, 0, LENGTH_UNSET, key)))
.isEqualTo(key);
// If not generates a new one using DataSpec.uri
assertThat(
CacheUtil.DEFAULT_CACHE_KEY_FACTORY.buildCacheKey(
new DataSpec(testUri, 0, LENGTH_UNSET, null)))
.isEqualTo(generateKey(testUri));
}
@Test
public void testGetCachedNoData() throws Exception { public void testGetCachedNoData() throws Exception {
CachingCounters counters = new CachingCounters(); CachingCounters counters = new CachingCounters();
CacheUtil.getCached(new DataSpec(Uri.parse("test")), mockCache, counters); CacheUtil.getCached(new DataSpec(Uri.parse("test")), mockCache, counters);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment