/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.util.kotlin
import kotlinx.coroutines.CoroutineStart
import com.android.app.tracing.coroutines.asyncTraced as async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
/** Like [Iterable.flatMap] but executes each [transform] invocation in a separate coroutine. */
suspend fun Iterable.flatMapParallel(transform: suspend (A) -> Iterable): List =
mapParallel(transform).flatten()
/** Like [Iterable.mapNotNull] but executes each [transform] invocation in a separate coroutine. */
suspend fun Iterable.mapNotNullParallel(transform: suspend (A) -> B?): List =
mapParallel(transform).filterNotNull()
/** Like [Iterable.map] but executes each [transform] invocation in a separate coroutine. */
suspend fun Iterable.mapParallel(transform: suspend (A) -> B): List = coroutineScope {
map { async(start = CoroutineStart.LAZY) { transform(it) } }.awaitAll()
}
/** Like [mapValues] but executes each [transform] invocation in a separate coroutine. */
suspend fun Map.mapValuesParallel(
transform: suspend (Map.Entry) -> B
): Map = entries.mapParallel { it.key to transform(it) }.toMap()