Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7bfd1c4 authored by Steve Elliott's avatar Steve Elliott
Browse files

[kairos] state scope optimizations

Flag: com.android.systemui.status_bar_mobile_icon_kairos
Bug: 383172066
Test: atest
Change-Id: I6ac1fe36093990f76e4edd4b25efe52f2030b15b
parent 39120ff6
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import com.android.systemui.kairos.internal.Schedulable
import com.android.systemui.kairos.internal.StateImpl
import com.android.systemui.kairos.internal.StateSource
import com.android.systemui.kairos.internal.activated
import com.android.systemui.kairos.internal.cached
import com.android.systemui.kairos.internal.constInit
import com.android.systemui.kairos.internal.constState
import com.android.systemui.kairos.internal.filterImpl
@@ -227,13 +226,12 @@ class MutableState<T> internal constructor(internal val network: Network, initia
        val changes = input.impl
        val name = null
        val operatorName = "MutableState"
        val state: StateSource<T> = StateSource(initialValue)
        val state: StateSource<T> = StateSource(initialValue, name, operatorName)
        val mapImpl = mapImpl(upstream = { changes.activated() }) { it, _ -> it!!.value }
        val calm: EventsImpl<T> =
            filterImpl({ mapImpl }) { new ->
                new != state.getCurrentWithEpoch(evalScope = this).first
            }
                .cached()
        @Suppress("DeferredResultUnused")
        network.transaction("MutableState.init") {
            calm.activate(evalScope = this, downstream = Schedulable.S(state))?.let {
+1 −2
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ internal inline fun <A> filterImpl(
    crossinline getPulse: EvalScope.() -> EventsImpl<A>,
    crossinline f: EvalScope.(A) -> Boolean,
): EventsImpl<A> {
    val mapped =
        mapImpl(getPulse) { it, _ -> if (f(it)) Maybe.present(it) else Maybe.absent }.cached()
    val mapped = mapImpl(getPulse) { it, _ -> if (f(it)) Maybe.present(it) else Maybe.absent }
    return filterPresentImpl { mapped }
}
+2 −2
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ internal fun <K, V> constIncremental(
    operatorName: String,
    init: Map<K, V>,
): IncrementalImpl<K, V> =
    IncrementalImpl(name, operatorName, neverImpl, neverImpl, StateSource(init))
    IncrementalImpl(name, operatorName, neverImpl, neverImpl, StateSource(init, name, operatorName))

internal inline fun <K, V> activatedIncremental(
    name: String?,
@@ -44,7 +44,7 @@ internal inline fun <K, V> activatedIncremental(
    crossinline getPatches: EvalScope.() -> EventsImpl<Map<K, Maybe<V>>>,
    init: Lazy<Map<K, V>>,
): IncrementalImpl<K, V> {
    val store = StateSource(init)
    val store = StateSource(init, name, operatorName)
    val maybeChanges =
        mapImpl(getPatches) { patch, _ ->
                val (current, _) = store.getCurrentWithEpoch(evalScope = this)
+2 −2
Original line number Diff line number Diff line
@@ -394,8 +394,8 @@ internal inline fun <A> mergeNodes(
    name: String? = null,
    crossinline f: EvalScope.(A, A) -> A,
): EventsImpl<A> {
    val mergedThese = mergeNodes(name, getPulse, getOther)
    val merged =
    val mergedThese: EventsImpl<These<A, A>> = mergeNodes(name, getPulse, getOther)
    val merged: EventsImpl<A> =
        mapImpl({ mergedThese }) { these, _ -> these.merge { thiz, that -> f(thiz, that) } }
    return merged.cached()
}
+36 −17
Original line number Diff line number Diff line
@@ -89,8 +89,13 @@ internal sealed class StateStore<out S> {
    abstract fun getCurrentWithEpoch(evalScope: EvalScope): Pair<S, Long>
}

internal class StateSource<S>(init: Lazy<S>) : StateStore<S>() {
    constructor(init: S) : this(lazyOf(init))
internal class StateSource<S>(init: Lazy<S>, val name: String?, val operatorName: String) :
    StateStore<S>() {
    constructor(
        init: S,
        name: String?,
        operatorName: String,
    ) : this(lazyOf(init), name, operatorName)

    lateinit var upstreamConnection: NodeConnection<S>

@@ -113,14 +118,15 @@ internal class StateSource<S>(init: Lazy<S>) : StateStore<S>() {
        writeEpoch = evalScope.epoch + 1
    }

    override fun toString(): String = "StateImpl(current=$_current, writeEpoch=$writeEpoch)"
    override fun toString(): String =
        "StateImpl(name=$name, operator=$operatorName, current=$_current, writeEpoch=$writeEpoch)"

    fun getStorageUnsafe(): Maybe<S> =
        if (_current.isInitialized()) Maybe.present(_current.value) else Maybe.absent
}

internal fun <A> constState(name: String?, operatorName: String, init: A): StateImpl<A> =
    StateImpl(name, operatorName, neverImpl, StateSource(init))
    StateImpl(name, operatorName, neverImpl, StateSource(init, name, operatorName))

internal inline fun <A> activatedStateSource(
    name: String?,
@@ -129,9 +135,18 @@ internal inline fun <A> activatedStateSource(
    crossinline getChanges: EvalScope.() -> EventsImpl<A>,
    init: Lazy<A>,
): StateImpl<A> {
    val store = StateSource(init)
    val calm: EventsImpl<A> =
        filterImpl(getChanges) { new -> new != store.getCurrentWithEpoch(evalScope = this).first }
    val store = StateSource(init, name, operatorName)
    val newValues: EventsImpl<Maybe<A>> =
        mapImpl(getChanges) { new, _ ->
                if (new != store.getCurrentWithEpoch(evalScope = this).first) {
                    Maybe.present(new)
                } else {
                    Maybe.absent
                }
            }
            // cache this for consistency: getCurrentWithEpoch is technically impure
            .cached()
    val calm: EventsImpl<A> = filterPresentImpl { newValues }
    evalScope.scheduleOutput(
        OneShot {
            calm.activate(evalScope = this, downstream = Schedulable.S(store))?.let {
@@ -146,17 +161,21 @@ internal inline fun <A> activatedStateSource(
    return StateImpl(name, operatorName, calm, store)
}

private inline fun <A> EventsImpl<A>.calm(state: StateDerived<A>): EventsImpl<A> =
    filterImpl({ this@calm }) { new ->
private inline fun <A> EventsImpl<A>.calm(state: StateDerived<A>): EventsImpl<A> {
    val newValues =
        mapImpl({ this@calm }) { new, _ ->
                val (current, _) = state.getCurrentWithEpoch(evalScope = this)
                if (new != current) {
                    state.setCacheFromPush(new, epoch)
                true
                    Maybe.present(new)
                } else {
                false
                    Maybe.absent
                }
            }
            // cache this for consistency: it is impure due to setCacheFromPush
            .cached()
    return filterPresentImpl { newValues }
}

internal fun <A, B> mapStateImplCheap(
    stateImpl: Init<StateImpl<A>>,
Loading