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 @@
### 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
on ExoPlayer via its source code rather than an AAR may need to add
`compileOptions { targetCompatibility JavaVersion.VERSION_1_8 }` to their
......
......@@ -119,6 +119,7 @@ public final class CacheDataSource implements DataSource {
private final DataSource cacheReadDataSource;
private final DataSource cacheWriteDataSource;
private final DataSource upstreamDataSource;
private final CacheKeyFactory cacheKeyFactory;
@Nullable private final EventListener eventListener;
private final boolean blockOnCache;
......@@ -178,8 +179,13 @@ public final class CacheDataSource implements DataSource {
*/
public CacheDataSource(Cache cache, DataSource upstream, @Flags int flags,
long maxCacheFileSize) {
this(cache, upstream, new FileDataSource(), new CacheDataSink(cache, maxCacheFileSize),
flags, null);
this(
cache,
upstream,
new FileDataSource(),
new CacheDataSink(cache, maxCacheFileSize),
flags,
/* eventListener= */ null);
}
/**
......@@ -198,8 +204,43 @@ public final class CacheDataSource implements DataSource {
*/
public CacheDataSource(Cache cache, DataSource upstream, DataSource cacheReadDataSource,
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.cacheReadDataSource = cacheReadDataSource;
this.cacheKeyFactory =
cacheKeyFactory != null ? cacheKeyFactory : CacheUtil.DEFAULT_CACHE_KEY_FACTORY;
this.blockOnCache = (flags & FLAG_BLOCK_ON_CACHE) != 0;
this.ignoreCacheOnError = (flags & FLAG_IGNORE_CACHE_ON_ERROR) != 0;
this.ignoreCacheForUnsetLengthRequests =
......@@ -216,7 +257,7 @@ public final class CacheDataSource implements DataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
try {
key = CacheUtil.getKey(dataSpec);
key = cacheKeyFactory.buildCacheKey(dataSpec);
uri = dataSpec.uri;
actualUri = getRedirectedUriOrDefault(cache, key, /* defaultUri= */ uri);
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 {
/** Default buffer size to be used while caching. */
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}.
*
......
......@@ -132,6 +132,22 @@ public final class CacheUtilTest {
}
@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 {
CachingCounters counters = new CachingCounters();
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