Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
42e69151
authored
Feb 08, 2019
by
olly
Committed by
Andrew Lewis
Feb 18, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Generate per-cache unique identifier.
PiperOrigin-RevId: 233030337
parent
dec00997
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
77 additions
and
18 deletions
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java
View file @
42e69151
...
...
@@ -22,6 +22,8 @@ import com.google.android.exoplayer2.C;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Log
;
import
java.io.File
;
import
java.io.IOException
;
import
java.security.SecureRandom
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
...
...
@@ -46,6 +48,8 @@ public final class SimpleCache implements Cache {
*/
private
static
final
int
SUBDIRECTORY_COUNT
=
10
;
private
static
final
String
UID_FILE_SUFFIX
=
".uid"
;
private
static
final
HashSet
<
File
>
lockedCacheDirs
=
new
HashSet
<>();
private
static
boolean
cacheFolderLockingDisabled
;
...
...
@@ -411,16 +415,25 @@ public final class SimpleCache implements Cache {
return
;
}
File
[]
files
=
cacheDir
.
listFiles
();
long
uid
=
0
;
try
{
uid
=
loadUid
(
cacheDir
,
files
);
}
catch
(
IOException
e
)
{
// TODO: Decide how to handle this.
}
// TODO: Pass the UID to the index, and use it.
contentIndex
.
load
();
if
(
fileIndex
!=
null
)
{
Map
<
String
,
CacheFileMetadata
>
fileMetadata
=
fileIndex
.
getAll
();
loadDirectory
(
cacheDir
,
/* isRoot= */
true
,
fileMetadata
);
loadDirectory
(
cacheDir
,
/* isRoot= */
true
,
file
s
,
file
Metadata
);
fileIndex
.
removeAll
(
fileMetadata
.
keySet
());
}
else
{
loadDirectory
(
cacheDir
,
/* isRoot= */
true
,
/* fileMetadata= */
null
);
loadDirectory
(
cacheDir
,
/* isRoot= */
true
,
files
,
/* fileMetadata= */
null
);
}
contentIndex
.
removeEmpty
();
try
{
contentIndex
.
store
();
}
catch
(
CacheException
e
)
{
...
...
@@ -431,37 +444,40 @@ public final class SimpleCache implements Cache {
/**
* Loads a cache directory. If the root directory is passed, also loads any subdirectories.
*
* @param directory The directory
to load
.
* @param directory The directory.
* @param isRoot Whether the directory is the root directory.
* @param files The files belonging to the directory.
* @param fileMetadata A mutable map containing cache file metadata, keyed by file name. The map
* is modified by removing entries for all loaded files. When the method call returns, the map
* will contain only metadata that was unused. May be null if no file metadata is available.
*/
private
void
loadDirectory
(
File
directory
,
boolean
isRoot
,
@Nullable
Map
<
String
,
CacheFileMetadata
>
fileMetadata
)
{
File
[]
files
=
directory
.
listFiles
();
if
(
files
==
null
)
{
// Not a directory.
return
;
}
if
(!
isRoot
&&
files
.
length
==
0
)
{
// Empty non-root directory.
directory
.
delete
();
File
directory
,
boolean
isRoot
,
File
[]
files
,
@Nullable
Map
<
String
,
CacheFileMetadata
>
fileMetadata
)
{
if
(
files
==
null
||
files
.
length
==
0
)
{
// Either (a) directory isn't really a directory (b) it's empty, or (c) listing files failed.
if
(!
isRoot
)
{
// For (a) and (b) deletion is the desired result. For (c) it will be a no-op if the
// directory is non-empty, so there's no harm in trying.
directory
.
delete
();
}
return
;
}
for
(
File
file
:
files
)
{
String
fileName
=
file
.
getName
();
if
(
isRoot
&&
fileName
.
indexOf
(
'.'
)
==
-
1
)
{
loadDirectory
(
file
,
/* isRoot= */
false
,
fileMetadata
);
loadDirectory
(
file
,
/* isRoot= */
false
,
file
.
listFiles
(),
file
Metadata
);
}
else
{
if
(
isRoot
&&
CachedContentIndex
.
isIndexFile
(
fileName
))
{
// Skip the (expected) index files in the root directory.
if
(
isRoot
&&
(
CachedContentIndex
.
isIndexFile
(
fileName
)
||
fileName
.
endsWith
(
UID_FILE_SUFFIX
)))
{
// Skip expected UID and index files in the root directory.
continue
;
}
CacheFileMetadata
metadata
=
fileMetadata
!=
null
?
fileMetadata
.
remove
(
file
.
getName
())
:
null
;
long
length
=
C
.
LENGTH_UNSET
;
long
lastAccessTimestamp
=
C
.
TIME_UNSET
;
CacheFileMetadata
metadata
=
fileMetadata
!=
null
?
fileMetadata
.
remove
(
fileName
)
:
null
;
if
(
metadata
!=
null
)
{
length
=
metadata
.
length
;
lastAccessTimestamp
=
metadata
.
lastAccessTimestamp
;
...
...
@@ -549,6 +565,49 @@ public final class SimpleCache implements Cache {
evictor
.
onSpanTouched
(
this
,
oldSpan
,
newSpan
);
}
/**
* Loads the cache UID from the files belonging to the root directory, generating one if needed.
*
* @param directory The root directory.
* @param files The files belonging to the rood directory.
* @return The cache loaded UID.
* @throws IOException If there is an error loading or generating the UID.
*/
private
static
long
loadUid
(
File
directory
,
File
[]
files
)
throws
IOException
{
for
(
File
file
:
files
)
{
String
fileName
=
file
.
getName
();
if
(
fileName
.
endsWith
(
UID_FILE_SUFFIX
))
{
try
{
return
parseUid
(
fileName
);
}
catch
(
NumberFormatException
e
)
{
// This should never happen, but if it does delete the malformed UID file and continue.
Log
.
e
(
TAG
,
"Malformed UID file: "
+
file
);
file
.
delete
();
}
}
}
return
createUid
(
directory
);
}
private
static
long
createUid
(
File
directory
)
throws
IOException
{
SecureRandom
random
=
new
SecureRandom
();
// Generate a non-negative UID.
long
uid
=
random
.
nextLong
();
uid
=
uid
==
Long
.
MIN_VALUE
?
0
:
Math
.
abs
(
uid
);
// Persist it as a file.
String
hexUid
=
Long
.
toString
(
uid
,
/* radix= */
16
);
File
hexUidFile
=
new
File
(
directory
,
hexUid
+
UID_FILE_SUFFIX
);
if
(!
hexUidFile
.
createNewFile
())
{
// False means that the file already exists, so this should never happen.
throw
new
IOException
(
"Failed to create UID file: "
+
hexUidFile
);
}
return
uid
;
}
private
static
long
parseUid
(
String
fileName
)
{
return
Long
.
parseLong
(
fileName
.
substring
(
0
,
fileName
.
indexOf
(
'.'
)),
/* radix= */
16
);
}
private
static
synchronized
boolean
lockFolder
(
File
cacheDir
)
{
if
(
cacheFolderLockingDisabled
)
{
return
true
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment