Merge "Use SieveCache instead of LruCache in .ui.text" into androidx-main
diff --git a/compose/ui/ui-text/build.gradle b/compose/ui/ui-text/build.gradle
index fa92639..47192fb 100644
--- a/compose/ui/ui-text/build.gradle
+++ b/compose/ui/ui-text/build.gradle
@@ -53,7 +53,9 @@
implementation(project(":compose:ui:ui-util"))
- implementation("androidx.collection:collection:1.4.0")
+ // TODO: Pin androidx.collection when SieveCache is available
+ // implementation("androidx.collection:collection:1.x.0")
+ implementation(project(":collection:collection"))
}
}
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidFontListTypeface.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidFontListTypeface.android.kt
index ba2a9c8..aaa9578 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidFontListTypeface.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidFontListTypeface.android.kt
@@ -21,9 +21,7 @@
import android.os.Build
import android.util.TypedValue
import androidx.annotation.RequiresApi
-import androidx.collection.LruCache
-import androidx.compose.ui.text.ExperimentalTextApi
-import androidx.compose.ui.text.android.InternalPlatformTextApi
+import androidx.collection.SieveCache
import androidx.compose.ui.text.font.AndroidFont
import androidx.compose.ui.text.font.AndroidPreloadedFont
import androidx.compose.ui.text.font.Font
@@ -110,18 +108,17 @@
internal object AndroidTypefaceCache {
// TODO multiple TypefaceCache's, would be good to unify
- private val cache = LruCache<String, Typeface>(16)
+ private val cache = SieveCache<String, Typeface>(16, 16)
/**
* Returns NativeTypeface for [font] if it is in cache. Otherwise create new NativeTypeface and
* put it into internal cache.
*/
- @OptIn(InternalPlatformTextApi::class, ExperimentalTextApi::class)
fun getOrCreate(context: Context, font: Font): Typeface {
val key = getKey(context, font)
key?.let {
- cache.get(key)?.let {
+ cache[key]?.let {
return it
}
}
@@ -139,13 +136,13 @@
else -> throw IllegalArgumentException("Unknown font type: $font")
} ?: throw IllegalArgumentException("Unable to load font $font")
- key?.let { cache.put(key, typeface) }
+ key?.let { cache[key] = typeface }
return typeface
}
/** Utility method to generate a key for caching purposes. */
- fun getKey(context: Context, font: Font): String? {
+ private fun getKey(context: Context, font: Font): String? {
return when (font) {
is ResourceFont -> {
val value = TypedValue()
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
index 3ca3629..f3fa771 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
@@ -16,7 +16,7 @@
package androidx.compose.ui.text
-import androidx.collection.LruCache
+import androidx.collection.SieveCache
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import androidx.compose.ui.text.font.FontFamily
@@ -80,8 +80,7 @@
* would miss the cache.
*/
@Immutable
-class TextMeasurer
-constructor(
+class TextMeasurer(
private val defaultFontFamilyResolver: FontFamily.Resolver,
private val defaultDensity: Density,
private val defaultLayoutDirection: LayoutDirection,
@@ -352,18 +351,18 @@
}
/**
- * Keeps an LRU layout cache of TextLayoutInput, TextLayoutResult pairs. Any non-layout affecting
- * change in TextLayoutInput (color, brush, shadow, TextDecoration) is ignored by this cache.
+ * Keeps a layout cache of TextLayoutInput, TextLayoutResult pairs. Any non-layout affecting change
+ * in TextLayoutInput (color, brush, shadow, TextDecoration) is ignored by this cache.
*
- * @param capacity Maximum size of LRU cache. Size unit is the number of [CacheTextLayoutInput] and
+ * @param capacity Maximum size of the cache. Size unit is the number of [CacheTextLayoutInput] and
* [TextLayoutResult] pairs.
* @throws IllegalArgumentException if capacity is not a positive integer.
*/
internal class TextLayoutCache(capacity: Int = DefaultCacheSize) {
- private val lruCache = LruCache<CacheTextLayoutInput, TextLayoutResult>(capacity)
+ private val cache = SieveCache<CacheTextLayoutInput, TextLayoutResult>(capacity, capacity)
fun get(key: TextLayoutInput): TextLayoutResult? {
- val resultFromCache = lruCache.get(CacheTextLayoutInput(key)) ?: return null
+ val resultFromCache = cache[CacheTextLayoutInput(key)] ?: return null
if (resultFromCache.multiParagraph.intrinsics.hasStaleResolvedFonts) {
// one of the resolved fonts has updated, and this MeasuredText is no longer valid for
@@ -375,11 +374,11 @@
}
fun put(key: TextLayoutInput, value: TextLayoutResult): TextLayoutResult? {
- return lruCache.put(CacheTextLayoutInput(key), value)
+ return cache.put(CacheTextLayoutInput(key), value)
}
fun remove(key: TextLayoutInput): TextLayoutResult? {
- return lruCache.remove(CacheTextLayoutInput(key))
+ return cache.remove(CacheTextLayoutInput(key))
}
}
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.kt
index 05b31aa..004da07 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.kt
@@ -16,7 +16,7 @@
package androidx.compose.ui.text.font
-import androidx.collection.LruCache
+import androidx.collection.SieveCache
import androidx.compose.runtime.State
import androidx.compose.ui.text.platform.createSynchronizedObject
import androidx.compose.ui.text.platform.synchronized
@@ -167,14 +167,14 @@
internal class TypefaceRequestCache {
internal val lock = createSynchronizedObject()
// @GuardedBy("lock")
- private val resultCache = LruCache<TypefaceRequest, TypefaceResult>(16)
+ private val resultCache = SieveCache<TypefaceRequest, TypefaceResult>(16, 16)
fun runCached(
typefaceRequest: TypefaceRequest,
resolveTypeface: ((TypefaceResult) -> Unit) -> TypefaceResult
): State<Any> {
synchronized(lock) {
- resultCache.get(typefaceRequest)?.let {
+ resultCache[typefaceRequest]?.let {
if (it.cacheable) {
return it
} else {
@@ -216,7 +216,7 @@
synchronized(lock) {
// async result may have completed prior to this block entering, do not overwrite
// final results
- if (resultCache.get(typefaceRequest) == null && currentTypefaceResult.cacheable) {
+ if (resultCache[typefaceRequest] == null && currentTypefaceResult.cacheable) {
resultCache.put(typefaceRequest, currentTypefaceResult)
}
}
@@ -230,7 +230,7 @@
for (i in typefaceRequests.indices) {
val typeRequest = typefaceRequests[i]
- val prior = synchronized(lock) { resultCache.get(typeRequest) }
+ val prior = synchronized(lock) { resultCache[typeRequest] }
if (prior != null) continue
val next =
@@ -244,15 +244,15 @@
// has async fonts in permanent cache
if (next is TypefaceResult.Async) continue
- synchronized(lock) { resultCache.put(typeRequest, next) }
+ synchronized(lock) { resultCache[typeRequest] = next }
}
}
// @VisibleForTesting
internal fun get(typefaceRequest: TypefaceRequest) =
- synchronized(lock) { resultCache.get(typefaceRequest) }
+ synchronized(lock) { resultCache[typefaceRequest] }
// @VisibleForTesting
internal val size: Int
- get() = synchronized(lock) { resultCache.size() }
+ get() = synchronized(lock) { resultCache.size }
}
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt
index c7ebfd0..54c0aa1 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.text.font
-import androidx.collection.LruCache
-import androidx.collection.SimpleArrayMap
+import androidx.collection.SieveCache
+import androidx.collection.mutableScatterMapOf
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -358,14 +358,14 @@
internal data class Key(val font: Font, val loaderKey: Any?)
- // 16 is based on the LruCache in TypefaceCompat Android, but no firm logic for this size.
+ // 16 is based on the cache in TypefaceCompat Android, but no firm logic for this size.
// After loading, fonts are put into the resultCache to allow reading from a kotlin function
// context, reducing async fonts overhead cache lookup overhead only while cached
// @GuardedBy("cacheLock")
- private val resultCache = LruCache<Key, AsyncTypefaceResult>(16)
+ private val resultCache = SieveCache<Key, AsyncTypefaceResult>(16, 16)
// failures and preloads are permanent, so they are stored separately
// @GuardedBy("cacheLock")
- private val permanentCache = SimpleArrayMap<Key, AsyncTypefaceResult>()
+ private val permanentCache = mutableScatterMapOf<Key, AsyncTypefaceResult>()
private val cacheLock = createSynchronizedObject()
@@ -379,13 +379,13 @@
synchronized(cacheLock) {
when {
result == null -> {
- permanentCache.put(key, PermanentFailure)
+ permanentCache[key] = PermanentFailure
}
forever -> {
- permanentCache.put(key, AsyncTypefaceResult(result))
+ permanentCache[key] = AsyncTypefaceResult(result)
}
else -> {
- resultCache.put(key, AsyncTypefaceResult(result))
+ resultCache[key] = AsyncTypefaceResult(result)
}
}
}
@@ -393,7 +393,7 @@
fun get(font: Font, platformFontLoader: PlatformFontLoader): AsyncTypefaceResult? {
val key = Key(font, platformFontLoader.cacheKey)
- return synchronized(cacheLock) { resultCache.get(key) ?: permanentCache[key] }
+ return synchronized(cacheLock) { resultCache[key] ?: permanentCache[key] }
}
suspend fun runCached(
@@ -404,7 +404,7 @@
): Any? {
val key = Key(font, platformFontLoader.cacheKey)
synchronized(cacheLock) {
- val priorResult = resultCache.get(key) ?: permanentCache[key]
+ val priorResult = resultCache[key] ?: permanentCache[key]
if (priorResult != null) {
return priorResult.result
}
@@ -413,13 +413,13 @@
synchronized(cacheLock) {
when {
it == null -> {
- permanentCache.put(key, PermanentFailure)
+ permanentCache[key] = PermanentFailure
}
forever -> {
- permanentCache.put(key, AsyncTypefaceResult(it))
+ permanentCache[key] = AsyncTypefaceResult(it)
}
else -> {
- resultCache.put(key, AsyncTypefaceResult(it))
+ resultCache[key] = AsyncTypefaceResult(it)
}
}
}
@@ -433,7 +433,7 @@
): Any? {
synchronized(cacheLock) {
val key = Key(font, platformFontLoader.cacheKey)
- val priorResult = resultCache.get(key) ?: permanentCache[key]
+ val priorResult = resultCache[key] ?: permanentCache[key]
if (priorResult != null) {
return priorResult.result
}