mirror of
https://github.com/androidx/media.git
synced 2025-05-14 11:09:53 +08:00
Merge pull request #4000 from jianx9/dev-v2
Provide an option to skip file descriptor sync in CacheDataSink. closeCurrentOutputStream
This commit is contained in:
commit
650f96fd6e
@ -43,6 +43,7 @@ public final class CacheDataSink implements DataSink {
|
||||
private final Cache cache;
|
||||
private final long maxCacheFileSize;
|
||||
private final int bufferSize;
|
||||
private final boolean syncFileDescriptor;
|
||||
|
||||
private DataSpec dataSpec;
|
||||
private File file;
|
||||
@ -72,7 +73,20 @@ public final class CacheDataSink implements DataSink {
|
||||
* multiple cache files.
|
||||
*/
|
||||
public CacheDataSink(Cache cache, long maxCacheFileSize) {
|
||||
this(cache, maxCacheFileSize, DEFAULT_BUFFER_SIZE);
|
||||
this(cache, maxCacheFileSize, DEFAULT_BUFFER_SIZE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CacheDataSink using the {@link #DEFAULT_BUFFER_SIZE}.
|
||||
*
|
||||
* @param cache The cache into which data should be written.
|
||||
* @param maxCacheFileSize The maximum size of a cache file, in bytes. If the sink is opened for
|
||||
* a {@link DataSpec} whose size exceeds this value, then the data will be fragmented into
|
||||
* multiple cache files.
|
||||
* @param syncFileDescriptor Skip file descriptor sync when closing current output stream.
|
||||
*/
|
||||
public CacheDataSink(Cache cache, long maxCacheFileSize, boolean syncFileDescriptor) {
|
||||
this(cache, maxCacheFileSize, DEFAULT_BUFFER_SIZE, syncFileDescriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,11 +96,13 @@ public final class CacheDataSink implements DataSink {
|
||||
* multiple cache files.
|
||||
* @param bufferSize The buffer size in bytes for writing to a cache file. A zero or negative
|
||||
* value disables buffering.
|
||||
* @param syncFileDescriptor Sync file descriptor when closing current output stream.
|
||||
*/
|
||||
public CacheDataSink(Cache cache, long maxCacheFileSize, int bufferSize) {
|
||||
public CacheDataSink(Cache cache, long maxCacheFileSize, int bufferSize, boolean syncFileDescriptor) {
|
||||
this.cache = Assertions.checkNotNull(cache);
|
||||
this.maxCacheFileSize = maxCacheFileSize;
|
||||
this.bufferSize = bufferSize;
|
||||
this.syncFileDescriptor = syncFileDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -170,7 +186,9 @@ public final class CacheDataSink implements DataSink {
|
||||
boolean success = false;
|
||||
try {
|
||||
outputStream.flush();
|
||||
underlyingFileOutputStream.getFD().sync();
|
||||
if (syncFileDescriptor) {
|
||||
underlyingFileOutputStream.getFD().sync();
|
||||
}
|
||||
success = true;
|
||||
} finally {
|
||||
Util.closeQuietly(outputStream);
|
||||
|
@ -44,7 +44,7 @@ public final class CacheDataSinkFactory implements DataSink.Factory {
|
||||
|
||||
@Override
|
||||
public DataSink createDataSink() {
|
||||
return new CacheDataSink(cache, maxCacheFileSize, bufferSize);
|
||||
return new CacheDataSink(cache, maxCacheFileSize, bufferSize, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -79,29 +79,49 @@ public final class CacheDataSourceTest {
|
||||
|
||||
@Test
|
||||
public void testCacheAndRead() throws Exception {
|
||||
assertCacheAndRead(false, false);
|
||||
assertCacheAndRead(false, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheAndReadUnboundedRequest() throws Exception {
|
||||
assertCacheAndRead(true, false);
|
||||
assertCacheAndRead(true, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheAndReadUnknownLength() throws Exception {
|
||||
assertCacheAndRead(false, true);
|
||||
assertCacheAndRead(false, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheAndReadUnboundedRequestUnknownLength() throws Exception {
|
||||
assertCacheAndRead(true, true);
|
||||
assertCacheAndRead(true, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheAndReadSkipFDSync() throws Exception {
|
||||
assertCacheAndRead(false, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheAndReadUnboundedRequestSkipFDSync() throws Exception {
|
||||
assertCacheAndRead(true, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheAndReadUnknownLengthSkipFDSync() throws Exception {
|
||||
assertCacheAndRead(false, true, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheAndReadUnboundedRequestUnknownLengthSkipFDSync() throws Exception {
|
||||
assertCacheAndRead(true, true, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsatisfiableRange() throws Exception {
|
||||
// Bounded request but the content length is unknown. This forces all data to be cached but not
|
||||
// the length
|
||||
assertCacheAndRead(false, true);
|
||||
assertCacheAndRead(false, true, true);
|
||||
|
||||
// Now do an unbounded request. This will read all of the data from cache and then try to read
|
||||
// more from upstream which will cause to a 416 so CDS will store the length.
|
||||
@ -347,10 +367,11 @@ public final class CacheDataSourceTest {
|
||||
cacheDataSource.close();
|
||||
}
|
||||
|
||||
private void assertCacheAndRead(boolean unboundedRequest, boolean simulateUnknownLength)
|
||||
private void assertCacheAndRead(boolean unboundedRequest, boolean simulateUnknownLength,
|
||||
boolean syncFD)
|
||||
throws IOException {
|
||||
// Read all data from upstream and write to cache
|
||||
CacheDataSource cacheDataSource = createCacheDataSource(false, simulateUnknownLength);
|
||||
CacheDataSource cacheDataSource = createCacheDataSource(false, simulateUnknownLength, syncFD);
|
||||
assertReadDataContentLength(cacheDataSource, unboundedRequest, simulateUnknownLength);
|
||||
|
||||
// Just read from cache
|
||||
@ -391,14 +412,19 @@ public final class CacheDataSourceTest {
|
||||
|
||||
private CacheDataSource createCacheDataSource(boolean setReadException,
|
||||
boolean simulateUnknownLength) {
|
||||
return createCacheDataSource(setReadException, simulateUnknownLength,
|
||||
CacheDataSource.FLAG_BLOCK_ON_CACHE);
|
||||
return createCacheDataSource(setReadException, simulateUnknownLength, true);
|
||||
}
|
||||
|
||||
private CacheDataSource createCacheDataSource(boolean setReadException,
|
||||
boolean simulateUnknownLength, @CacheDataSource.Flags int flags) {
|
||||
boolean simulateUnknownLength, boolean syncFD) {
|
||||
return createCacheDataSource(setReadException, simulateUnknownLength,
|
||||
CacheDataSource.FLAG_BLOCK_ON_CACHE, syncFD);
|
||||
}
|
||||
|
||||
private CacheDataSource createCacheDataSource(boolean setReadException,
|
||||
boolean simulateUnknownLength, @CacheDataSource.Flags int flags, boolean syncFD) {
|
||||
return createCacheDataSource(setReadException, simulateUnknownLength, flags,
|
||||
new CacheDataSink(cache, MAX_CACHE_FILE_SIZE));
|
||||
new CacheDataSink(cache, MAX_CACHE_FILE_SIZE, syncFD));
|
||||
}
|
||||
|
||||
private CacheDataSource createCacheDataSource(boolean setReadException,
|
||||
|
Loading…
x
Reference in New Issue
Block a user