importMaven threadsafe set of written files
in case LocalMavenRepoDownloader is called from multiple threads at once
Bug: 268388000
Test: cherry-pick the following change that increases the number of writes to the set, and then run \
`./development/importMaven/importMaven.sh com.android.tools.metalava:metalava:1.0.0-alpha07 --metalava-build-id=9581773 --redownload`
Change-Id: I0d0aacca33b9e57f55494b80ab418b9b26b420ee
diff --git a/development/importMaven/src/main/kotlin/androidx/build/importMaven/LocalMavenRepoDownloader.kt b/development/importMaven/src/main/kotlin/androidx/build/importMaven/LocalMavenRepoDownloader.kt
index cc106b9..57f1259 100644
--- a/development/importMaven/src/main/kotlin/androidx/build/importMaven/LocalMavenRepoDownloader.kt
+++ b/development/importMaven/src/main/kotlin/androidx/build/importMaven/LocalMavenRepoDownloader.kt
@@ -22,6 +22,7 @@
import org.jetbrains.kotlin.com.google.common.annotations.VisibleForTesting
import java.security.MessageDigest
import java.util.Locale
+import java.util.concurrent.ConcurrentHashMap
/**
* A [DownloadObserver] that will save all files into the given repository folders.
@@ -39,12 +40,13 @@
) : DownloadObserver {
private val logger = logger("LocalMavenRepoDownloader")
private val licenseDownloader = LicenseDownloader(enableGithubApi = false)
- private val writtenFiles = mutableSetOf<Path>()
+ private val writtenFilesMap: MutableMap<Path, Boolean> = ConcurrentHashMap<Path, Boolean>()
+ fun writtenFiles(): Set<Path> = writtenFilesMap.keys
/**
* Returns the list of files we've downloaded.
*/
- fun getDownloadedFiles() = writtenFiles.sorted().distinct()
+ fun getDownloadedFiles() = writtenFiles()
override fun onDownload(path: String, bytes: ByteArray) {
if (path.substringAfterLast('.') in checksumExtensions) {
@@ -118,7 +120,7 @@
file: Path,
contents: ByteArray
) {
- writtenFiles.add(file.normalized())
+ writtenFilesMap.put(file.normalized(), true)
file.parent?.let(fileSystem::createDirectories)
write(
file = file,
@@ -144,7 +146,7 @@
* might delete files that were resolved from the local repository.
*/
fun cleanupLocalRepositories() {
- val folders = writtenFiles.filter {
+ val folders = writtenFiles().filter {
val isDirectory = fileSystem.metadata(it).isDirectory
!isDirectory && it.name.substringAfterLast(".") in EXTENSIONS_FOR_CLENAUP
}.mapNotNull {
@@ -160,7 +162,7 @@
"Cleaning up $folder ($index of ${folders.size})"
}
fileSystem.list(folder).forEach { candidateToDelete ->
- if (!writtenFiles.contains(candidateToDelete.normalized())) {
+ if (!writtenFiles().contains(candidateToDelete.normalized())) {
logger.trace {
"Deleting $candidateToDelete since it is not re-downloaded"
}
@@ -255,4 +257,4 @@
return signatureFileName to resultBytes
}
}
-}
\ No newline at end of file
+}