mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Automated g4 rollback of changelist 239294713.
*** Reason for rollback *** Trying to forward fix instead. *** Original change description *** Automated g4 rollback of changelist 237051112. *** Original change description *** Add SimpleCache deletion functionality This is needed now that index data may be stored outside of the cache directory. *** *** PiperOrigin-RevId: 239429430
This commit is contained in:
parent
f7f5009883
commit
3abf5ed143
3 changed files with 146 additions and 34 deletions
|
|
@ -61,6 +61,34 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
@MonotonicNonNull private String tableName;
|
@MonotonicNonNull private String tableName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes index data for the specified cache.
|
||||||
|
*
|
||||||
|
* @param databaseProvider Provides the database in which the index is stored.
|
||||||
|
* @param uid The cache UID.
|
||||||
|
* @throws DatabaseIOException If an error occurs deleting the index data.
|
||||||
|
*/
|
||||||
|
public static void delete(DatabaseProvider databaseProvider, long uid)
|
||||||
|
throws DatabaseIOException {
|
||||||
|
String hexUid = Long.toHexString(uid);
|
||||||
|
try {
|
||||||
|
String tableName = getTableName(hexUid);
|
||||||
|
SQLiteDatabase writableDatabase = databaseProvider.getWritableDatabase();
|
||||||
|
writableDatabase.beginTransaction();
|
||||||
|
try {
|
||||||
|
VersionTable.removeVersion(
|
||||||
|
writableDatabase, VersionTable.FEATURE_CACHE_FILE_METADATA, hexUid);
|
||||||
|
dropTable(writableDatabase, tableName);
|
||||||
|
writableDatabase.setTransactionSuccessful();
|
||||||
|
} finally {
|
||||||
|
writableDatabase.endTransaction();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DatabaseIOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param databaseProvider Provides the database in which the index is stored. */
|
||||||
public CacheFileMetadataIndex(DatabaseProvider databaseProvider) {
|
public CacheFileMetadataIndex(DatabaseProvider databaseProvider) {
|
||||||
this.databaseProvider = databaseProvider;
|
this.databaseProvider = databaseProvider;
|
||||||
}
|
}
|
||||||
|
|
@ -68,12 +96,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
/**
|
/**
|
||||||
* Initializes the index for the given cache UID.
|
* Initializes the index for the given cache UID.
|
||||||
*
|
*
|
||||||
|
* @param uid The cache UID.
|
||||||
* @throws DatabaseIOException If an error occurs initializing the index.
|
* @throws DatabaseIOException If an error occurs initializing the index.
|
||||||
*/
|
*/
|
||||||
public void initialize(long uid) throws DatabaseIOException {
|
public void initialize(long uid) throws DatabaseIOException {
|
||||||
try {
|
try {
|
||||||
String hexUid = Long.toHexString(uid);
|
String hexUid = Long.toHexString(uid);
|
||||||
tableName = TABLE_PREFIX + hexUid;
|
tableName = getTableName(hexUid);
|
||||||
SQLiteDatabase readableDatabase = databaseProvider.getReadableDatabase();
|
SQLiteDatabase readableDatabase = databaseProvider.getReadableDatabase();
|
||||||
int version =
|
int version =
|
||||||
VersionTable.getVersion(
|
VersionTable.getVersion(
|
||||||
|
|
@ -84,7 +113,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
try {
|
try {
|
||||||
VersionTable.setVersion(
|
VersionTable.setVersion(
|
||||||
writableDatabase, VersionTable.FEATURE_CACHE_FILE_METADATA, hexUid, TABLE_VERSION);
|
writableDatabase, VersionTable.FEATURE_CACHE_FILE_METADATA, hexUid, TABLE_VERSION);
|
||||||
writableDatabase.execSQL("DROP TABLE IF EXISTS " + tableName);
|
dropTable(writableDatabase, tableName);
|
||||||
writableDatabase.execSQL("CREATE TABLE " + tableName + " " + TABLE_SCHEMA);
|
writableDatabase.execSQL("CREATE TABLE " + tableName + " " + TABLE_SCHEMA);
|
||||||
writableDatabase.setTransactionSuccessful();
|
writableDatabase.setTransactionSuccessful();
|
||||||
} finally {
|
} finally {
|
||||||
|
|
@ -196,4 +225,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
/* having= */ null,
|
/* having= */ null,
|
||||||
/* orderBy= */ null);
|
/* orderBy= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void dropTable(SQLiteDatabase writableDatabase, String tableName) {
|
||||||
|
writableDatabase.execSQL("DROP TABLE IF EXISTS " + tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTableName(String hexUid) {
|
||||||
|
return TABLE_PREFIX + hexUid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,18 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
return fileName.startsWith(FILE_NAME_ATOMIC);
|
return fileName.startsWith(FILE_NAME_ATOMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes index data for the specified cache.
|
||||||
|
*
|
||||||
|
* @param databaseProvider Provides the database in which the index is stored.
|
||||||
|
* @param uid The cache UID.
|
||||||
|
* @throws DatabaseIOException If an error occurs deleting the index data.
|
||||||
|
*/
|
||||||
|
public static void delete(DatabaseProvider databaseProvider, long uid)
|
||||||
|
throws DatabaseIOException {
|
||||||
|
DatabaseStorage.delete(databaseProvider, uid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance supporting database storage only.
|
* Creates an instance supporting database storage only.
|
||||||
*
|
*
|
||||||
|
|
@ -717,6 +729,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
private String hexUid;
|
private String hexUid;
|
||||||
private String tableName;
|
private String tableName;
|
||||||
|
|
||||||
|
public static void delete(DatabaseProvider databaseProvider, long uid)
|
||||||
|
throws DatabaseIOException {
|
||||||
|
delete(databaseProvider, Long.toHexString(uid));
|
||||||
|
}
|
||||||
|
|
||||||
public DatabaseStorage(DatabaseProvider databaseProvider) {
|
public DatabaseStorage(DatabaseProvider databaseProvider) {
|
||||||
this.databaseProvider = databaseProvider;
|
this.databaseProvider = databaseProvider;
|
||||||
pendingUpdates = new SparseArray<>();
|
pendingUpdates = new SparseArray<>();
|
||||||
|
|
@ -725,7 +742,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
@Override
|
@Override
|
||||||
public void initialize(long uid) {
|
public void initialize(long uid) {
|
||||||
hexUid = Long.toHexString(uid);
|
hexUid = Long.toHexString(uid);
|
||||||
tableName = TABLE_PREFIX + hexUid;
|
tableName = getTableName(hexUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -739,20 +756,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() throws DatabaseIOException {
|
public void delete() throws DatabaseIOException {
|
||||||
try {
|
delete(databaseProvider, hexUid);
|
||||||
SQLiteDatabase writableDatabase = databaseProvider.getWritableDatabase();
|
|
||||||
writableDatabase.beginTransaction();
|
|
||||||
try {
|
|
||||||
VersionTable.removeVersion(
|
|
||||||
writableDatabase, VersionTable.FEATURE_CACHE_CONTENT_METADATA, hexUid);
|
|
||||||
dropTable(writableDatabase);
|
|
||||||
writableDatabase.setTransactionSuccessful();
|
|
||||||
} finally {
|
|
||||||
writableDatabase.endTransaction();
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new DatabaseIOException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -875,14 +879,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
private void initializeTable(SQLiteDatabase writableDatabase) throws DatabaseIOException {
|
private void initializeTable(SQLiteDatabase writableDatabase) throws DatabaseIOException {
|
||||||
VersionTable.setVersion(
|
VersionTable.setVersion(
|
||||||
writableDatabase, VersionTable.FEATURE_CACHE_CONTENT_METADATA, hexUid, TABLE_VERSION);
|
writableDatabase, VersionTable.FEATURE_CACHE_CONTENT_METADATA, hexUid, TABLE_VERSION);
|
||||||
dropTable(writableDatabase);
|
dropTable(writableDatabase, tableName);
|
||||||
writableDatabase.execSQL("CREATE TABLE " + tableName + " " + TABLE_SCHEMA);
|
writableDatabase.execSQL("CREATE TABLE " + tableName + " " + TABLE_SCHEMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dropTable(SQLiteDatabase writableDatabase) {
|
|
||||||
writableDatabase.execSQL("DROP TABLE IF EXISTS " + tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deleteRow(SQLiteDatabase writableDatabase, int key) {
|
private void deleteRow(SQLiteDatabase writableDatabase, int key) {
|
||||||
writableDatabase.delete(tableName, WHERE_ID_EQUALS, new String[] {Integer.toString(key)});
|
writableDatabase.delete(tableName, WHERE_ID_EQUALS, new String[] {Integer.toString(key)});
|
||||||
}
|
}
|
||||||
|
|
@ -899,5 +899,32 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
values.put(COLUMN_METADATA, data);
|
values.put(COLUMN_METADATA, data);
|
||||||
writableDatabase.replaceOrThrow(tableName, /* nullColumnHack= */ null, values);
|
writableDatabase.replaceOrThrow(tableName, /* nullColumnHack= */ null, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void delete(DatabaseProvider databaseProvider, String hexUid)
|
||||||
|
throws DatabaseIOException {
|
||||||
|
try {
|
||||||
|
String tableName = getTableName(hexUid);
|
||||||
|
SQLiteDatabase writableDatabase = databaseProvider.getWritableDatabase();
|
||||||
|
writableDatabase.beginTransaction();
|
||||||
|
try {
|
||||||
|
VersionTable.removeVersion(
|
||||||
|
writableDatabase, VersionTable.FEATURE_CACHE_CONTENT_METADATA, hexUid);
|
||||||
|
dropTable(writableDatabase, tableName);
|
||||||
|
writableDatabase.setTransactionSuccessful();
|
||||||
|
} finally {
|
||||||
|
writableDatabase.endTransaction();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DatabaseIOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void dropTable(SQLiteDatabase writableDatabase, String tableName) {
|
||||||
|
writableDatabase.execSQL("DROP TABLE IF EXISTS " + tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTableName(String hexUid) {
|
||||||
|
return TABLE_PREFIX + hexUid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,11 @@ import android.os.ConditionVariable;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.database.DatabaseIOException;
|
||||||
import com.google.android.exoplayer2.database.DatabaseProvider;
|
import com.google.android.exoplayer2.database.DatabaseProvider;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
@ -36,8 +38,13 @@ import java.util.TreeSet;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Cache} implementation that maintains an in-memory representation. Note, only one
|
* A {@link Cache} implementation that maintains an in-memory representation.
|
||||||
* instance of SimpleCache is allowed for a given directory at a given time.
|
*
|
||||||
|
* <p>Only one instance of SimpleCache is allowed for a given directory at a given time.
|
||||||
|
*
|
||||||
|
* <p>To delete a SimpleCache, use {@link #delete(File, DatabaseProvider)} rather than deleting the
|
||||||
|
* directory and its contents directly. This is necessary to ensure that associated index data is
|
||||||
|
* also removed.
|
||||||
*/
|
*/
|
||||||
public final class SimpleCache implements Cache {
|
public final class SimpleCache implements Cache {
|
||||||
|
|
||||||
|
|
@ -93,6 +100,45 @@ public final class SimpleCache implements Cache {
|
||||||
lockedCacheDirs.clear();
|
lockedCacheDirs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all content belonging to a cache instance.
|
||||||
|
*
|
||||||
|
* @param cacheDir The cache directory.
|
||||||
|
* @param databaseProvider The database in which index data is stored, or {@code null} if the
|
||||||
|
* cache used a legacy index.
|
||||||
|
*/
|
||||||
|
public static void delete(File cacheDir, @Nullable DatabaseProvider databaseProvider) {
|
||||||
|
if (!cacheDir.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File[] files = cacheDir.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
cacheDir.delete();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (databaseProvider != null) {
|
||||||
|
// Make a best effort to read the cache UID and delete associated index data before deleting
|
||||||
|
// cache directory itself.
|
||||||
|
long uid = loadUid(files);
|
||||||
|
if (uid != -1) {
|
||||||
|
try {
|
||||||
|
CacheFileMetadataIndex.delete(databaseProvider, uid);
|
||||||
|
} catch (DatabaseIOException e) {
|
||||||
|
Log.w(TAG, "Failed to delete file metadata: " + uid);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CachedContentIndex.delete(databaseProvider, uid);
|
||||||
|
} catch (DatabaseIOException e) {
|
||||||
|
Log.w(TAG, "Failed to delete file metadata: " + uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Util.recursiveDelete(cacheDir);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the cache. The cache will delete any unrecognized files from the directory. Hence
|
* Constructs the cache. The cache will delete any unrecognized files from the directory. Hence
|
||||||
* the directory cannot be used to store other files.
|
* the directory cannot be used to store other files.
|
||||||
|
|
@ -524,11 +570,14 @@ public final class SimpleCache implements Cache {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
uid = loadUid(files);
|
||||||
uid = loadUid(cacheDir, files);
|
if (uid == -1) {
|
||||||
} catch (IOException e) {
|
try {
|
||||||
initializationException = new CacheException("Failed to load cache UID: " + cacheDir);
|
uid = createUid(cacheDir);
|
||||||
return;
|
} catch (IOException e) {
|
||||||
|
initializationException = new CacheException("Failed to create cache UID: " + cacheDir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -686,14 +735,13 @@ public final class SimpleCache implements Cache {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the cache UID from the files belonging to the root directory, generating one if needed.
|
* Loads the cache UID from the files belonging to the root directory.
|
||||||
*
|
*
|
||||||
* @param directory The root directory.
|
|
||||||
* @param files The files belonging to the root directory.
|
* @param files The files belonging to the root directory.
|
||||||
* @return The cache loaded UID.
|
* @return The loaded UID, or -1 if a UID has not yet been created.
|
||||||
* @throws IOException If there is an error loading or generating the UID.
|
* @throws IOException If there is an error loading or generating the UID.
|
||||||
*/
|
*/
|
||||||
private static long loadUid(File directory, File[] files) throws IOException {
|
private static long loadUid(File[] files) {
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
String fileName = file.getName();
|
String fileName = file.getName();
|
||||||
if (fileName.endsWith(UID_FILE_SUFFIX)) {
|
if (fileName.endsWith(UID_FILE_SUFFIX)) {
|
||||||
|
|
@ -706,7 +754,7 @@ public final class SimpleCache implements Cache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return createUid(directory);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("TrulyRandom")
|
@SuppressWarnings("TrulyRandom")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue