mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
fix: make ApiVersionsRegistry thread-safe
This commit is contained in:
+8
-7
@@ -19,14 +19,15 @@ package com.itsaky.androidide.xml.internal.versions
|
||||
|
||||
import com.itsaky.androidide.xml.versions.ApiVersion
|
||||
import com.itsaky.androidide.xml.versions.ApiVersions
|
||||
import org.eclipse.jdt.core.Signature
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
/** @author Akash Yadav */
|
||||
/**
|
||||
* This implementation is not thread safe. Do not modify concurrently.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
internal class DefaultApiVersions : ApiVersions {
|
||||
|
||||
val classes =
|
||||
ConcurrentHashMap<String, Pair<ApiVersion?, ConcurrentHashMap<String, ApiVersion>>>()
|
||||
val classes = HashMap<String, Pair<ApiVersion?, HashMap<String, ApiVersion>>>()
|
||||
|
||||
private fun String.flatten() = replace('.', '/')
|
||||
|
||||
@@ -57,9 +58,9 @@ internal class DefaultApiVersions : ApiVersions {
|
||||
private fun computeClass(
|
||||
name: String,
|
||||
version: ApiVersion? = null
|
||||
): Pair<ApiVersion?, ConcurrentHashMap<String, ApiVersion>> {
|
||||
): Pair<ApiVersion?, HashMap<String, ApiVersion>> {
|
||||
return classes.computeIfAbsent(name.flatten()) {
|
||||
version to ConcurrentHashMap()
|
||||
version to hashMapOf()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+44
-45
@@ -33,7 +33,7 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
*/
|
||||
@AutoService(ApiVersionsRegistry::class)
|
||||
@VisibleForTesting
|
||||
class DefaultApiVersionsRegistry : ApiVersionsParser(), ApiVersionsRegistry {
|
||||
class DefaultApiVersionsRegistry : ApiVersionsRegistry {
|
||||
|
||||
private val versions = ConcurrentHashMap<String, ApiVersions>()
|
||||
|
||||
@@ -43,10 +43,6 @@ class DefaultApiVersionsRegistry : ApiVersionsParser(), ApiVersionsRegistry {
|
||||
|
||||
override var isLoggingEnabled: Boolean = true
|
||||
|
||||
private var _currentApiVersions: DefaultApiVersions? = null
|
||||
private val currentApiVersions: DefaultApiVersions
|
||||
get() = checkNotNull(_currentApiVersions)
|
||||
|
||||
override fun forPlatformDir(platform: File): ApiVersions? {
|
||||
var version = versions[platform.path]
|
||||
if (version != null) {
|
||||
@@ -69,50 +65,53 @@ class DefaultApiVersionsRegistry : ApiVersionsParser(), ApiVersionsRegistry {
|
||||
}
|
||||
|
||||
return versionsFile.inputStream().buffered().use { inputStream ->
|
||||
check(_currentApiVersions == null)
|
||||
_currentApiVersions = DefaultApiVersions()
|
||||
parse(inputStream)
|
||||
currentApiVersions.also {
|
||||
_currentApiVersions = null
|
||||
}
|
||||
// we do not implement the parsing logic in the registry itself for thread safety
|
||||
val versions = DefaultApiVersions()
|
||||
val parser = ApiVersionsParserInternal(versions)
|
||||
parser.parse(inputStream)
|
||||
versions
|
||||
}
|
||||
}
|
||||
|
||||
override fun isDuplicateClass(name: String): Boolean {
|
||||
return currentApiVersions.containsClass(name)
|
||||
}
|
||||
|
||||
override fun isDuplicateMember(className: String, memberName: String): Boolean {
|
||||
return currentApiVersions.containsClassMember(className, memberName)
|
||||
}
|
||||
|
||||
override fun consumeClassVersionInfo(name: String, apiVersion: ApiVersion) {
|
||||
if (apiVersion.isSinceInception()) {
|
||||
return
|
||||
}
|
||||
currentApiVersions.putClass(name, apiVersion)
|
||||
}
|
||||
|
||||
override fun consumeMemberVersionInfo(
|
||||
className: String,
|
||||
member: String,
|
||||
memberType: String,
|
||||
apiVersion: ApiVersion
|
||||
) {
|
||||
if (apiVersion.isSinceInception()) {
|
||||
return
|
||||
}
|
||||
|
||||
var identifier = member
|
||||
if (memberType == TAG_METHOD) {
|
||||
// strip return type to save some memory
|
||||
identifier = member.substring(0, member.lastIndexOf(')') + 1)
|
||||
}
|
||||
|
||||
currentApiVersions.putMember(className, identifier, apiVersion)
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
versions.clear()
|
||||
}
|
||||
|
||||
private class ApiVersionsParserInternal(
|
||||
private val currentApiVersions: DefaultApiVersions
|
||||
) : ApiVersionsParser() {
|
||||
override fun isDuplicateClass(name: String): Boolean {
|
||||
return currentApiVersions.containsClass(name)
|
||||
}
|
||||
|
||||
override fun isDuplicateMember(className: String, memberName: String): Boolean {
|
||||
return currentApiVersions.containsClassMember(className, memberName)
|
||||
}
|
||||
|
||||
override fun consumeClassVersionInfo(name: String, apiVersion: ApiVersion) {
|
||||
if (apiVersion.isSinceInception()) {
|
||||
return
|
||||
}
|
||||
currentApiVersions.putClass(name, apiVersion)
|
||||
}
|
||||
|
||||
override fun consumeMemberVersionInfo(
|
||||
className: String,
|
||||
member: String,
|
||||
memberType: String,
|
||||
apiVersion: ApiVersion
|
||||
) {
|
||||
if (apiVersion.isSinceInception()) {
|
||||
return
|
||||
}
|
||||
|
||||
var identifier = member
|
||||
if (memberType == TAG_METHOD) {
|
||||
// strip return type to save some memory
|
||||
identifier = member.substring(0, member.lastIndexOf(')') + 1)
|
||||
}
|
||||
|
||||
currentApiVersions.putMember(className, identifier, apiVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user