Skip to content

Commit 45281c3

Browse files
committed
Improve parallel interface
Signed-off-by: Kyle Corry <[email protected]>
1 parent f1f6f07 commit 45281c3

File tree

4 files changed

+50
-29
lines changed

4 files changed

+50
-29
lines changed

app/src/main/java/com/kylecorry/trail_sense/shared/andromeda_temp/ParallelCoroutineRunner2.kt

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,70 @@ import kotlinx.coroutines.launch
55
import kotlinx.coroutines.sync.Semaphore
66
import kotlinx.coroutines.sync.withPermit
77

8-
class ParallelCoroutineRunner2(maxParallel: Int = 8) {
8+
object Parallel {
99

10-
private val semaphore = Semaphore(maxParallel)
10+
fun getProcessorCount(): Int {
11+
return Runtime.getRuntime().availableProcessors()
12+
}
13+
14+
private fun getDefaultMaxParallel(): Int {
15+
return getProcessorCount().coerceAtLeast(2)
16+
}
1117

12-
suspend fun run(coroutines: List<suspend () -> Any>) = coroutineScope {
13-
for (coroutine in coroutines) {
14-
launch {
15-
semaphore.withPermit { coroutine() }
18+
suspend fun forEach(
19+
coroutines: List<suspend () -> Any>,
20+
maxParallel: Int = getDefaultMaxParallel()
21+
) =
22+
coroutineScope {
23+
val semaphore = Semaphore(maxParallel)
24+
for (coroutine in coroutines) {
25+
launch {
26+
semaphore.withPermit { coroutine() }
27+
}
1628
}
1729
}
18-
}
1930

20-
suspend fun <R> run(items: List<R>, coroutine: suspend (R) -> Unit) {
21-
run(items.map { { coroutine(it) } })
31+
suspend fun <R> forEach(
32+
items: List<R>,
33+
maxParallel: Int = getDefaultMaxParallel(),
34+
coroutine: suspend (R) -> Unit
35+
) {
36+
forEach(items.map { { coroutine(it) } }, maxParallel)
2237
}
2338

24-
suspend fun <T> map(coroutines: List<suspend () -> T>): List<T> {
39+
suspend fun <T> map(
40+
coroutines: List<suspend () -> T>,
41+
maxParallel: Int = getDefaultMaxParallel()
42+
): List<T> {
2543
val items = mutableListOf<Pair<Int, T>>()
2644
val lock = Any()
2745

28-
run(coroutines.mapIndexed { index, coroutine ->
46+
forEach(coroutines.mapIndexed { index, coroutine ->
2947
{
3048
val item = coroutine()
3149
synchronized(lock) {
3250
items.add(index to item)
3351
}
3452
}
35-
})
53+
}, maxParallel)
3654

3755
return items.sortedBy { it.first }.map { it.second }
3856
}
3957

40-
suspend fun <T> mapFunctions(functions: List<() -> T>): List<T> {
41-
return map(functions.map { { it() } })
58+
suspend fun <T> mapFunctions(
59+
functions: List<() -> T>,
60+
maxParallel: Int = getDefaultMaxParallel()
61+
): List<T> {
62+
return map(functions.map { { it() } }, maxParallel)
4263
}
4364

44-
suspend fun <R, T> map(items: List<R>, coroutine: suspend (R) -> T): List<T> {
45-
return map(items.map { { coroutine(it) } })
65+
suspend fun <R, T> map(
66+
items: List<R>,
67+
maxParallel: Int = getDefaultMaxParallel(),
68+
coroutine: suspend (R) -> T
69+
): List<T> {
70+
return map(items.map { { coroutine(it) } }, maxParallel)
4671
}
4772

73+
4874
}

app/src/main/java/com/kylecorry/trail_sense/shared/map_layers/MapLayerBackgroundTask.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ package com.kylecorry.trail_sense.shared.map_layers
22

33
import com.kylecorry.andromeda.core.cache.AppServiceRegistry
44
import com.kylecorry.luna.coroutines.CoroutineQueueRunner
5-
import com.kylecorry.luna.coroutines.ParallelCoroutineRunner
65
import com.kylecorry.sol.science.geology.CoordinateBounds
7-
import com.kylecorry.trail_sense.shared.andromeda_temp.ParallelCoroutineRunner2
6+
import com.kylecorry.trail_sense.shared.andromeda_temp.Parallel
87
import com.kylecorry.trail_sense.shared.andromeda_temp.grow
98
import com.kylecorry.trail_sense.shared.device.DeviceSubsystem
109
import com.kylecorry.trail_sense.shared.map_layers.tiles.TileMath
@@ -63,8 +62,7 @@ class MapLayerBackgroundTask {
6362
val taskCopy = synchronized(taskLock) {
6463
tasks.toList()
6564
}
66-
val parallel = ParallelCoroutineRunner2()
67-
parallel.run(taskCopy.map { { it(bounds, metersPerPixel) } })
65+
Parallel.forEach(taskCopy.map { { it(bounds, metersPerPixel) } })
6866
}
6967
) {
7068

app/src/main/java/com/kylecorry/trail_sense/shared/map_layers/MapLayerBackgroundTask2.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ package com.kylecorry.trail_sense.shared.map_layers
22

33
import com.kylecorry.andromeda.core.cache.AppServiceRegistry
44
import com.kylecorry.luna.coroutines.CoroutineQueueRunner
5-
import com.kylecorry.luna.coroutines.ParallelCoroutineRunner
65
import com.kylecorry.sol.math.geometry.Rectangle
76
import com.kylecorry.sol.science.geology.CoordinateBounds
8-
import com.kylecorry.trail_sense.shared.andromeda_temp.ParallelCoroutineRunner2
7+
import com.kylecorry.trail_sense.shared.andromeda_temp.Parallel
98
import com.kylecorry.trail_sense.shared.andromeda_temp.grow
109
import com.kylecorry.trail_sense.shared.device.DeviceSubsystem
1110
import com.kylecorry.trail_sense.shared.map_layers.tiles.TileMath
@@ -66,8 +65,7 @@ class MapLayerBackgroundTask2 {
6665
val taskCopy = synchronized(taskLock) {
6766
tasks.toList()
6867
}
69-
val parallel = ParallelCoroutineRunner2()
70-
parallel.run(taskCopy.map { { it(viewBounds, bounds, projection) } })
68+
Parallel.forEach(taskCopy.map { { it(viewBounds, bounds, projection) } })
7169
}
7270
) {
7371

app/src/main/java/com/kylecorry/trail_sense/shared/map_layers/tiles/TileLoader.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import com.kylecorry.andromeda.bitmaps.operations.Conditional
1010
import com.kylecorry.andromeda.bitmaps.operations.Convert
1111
import com.kylecorry.andromeda.bitmaps.operations.ReplaceColor
1212
import com.kylecorry.andromeda.bitmaps.operations.applyOperationsOrNull
13-
import com.kylecorry.luna.coroutines.ParallelCoroutineRunner
1413
import com.kylecorry.luna.coroutines.onDefault
1514
import com.kylecorry.sol.science.geology.CoordinateBounds
15+
import com.kylecorry.trail_sense.shared.andromeda_temp.Parallel
1616
import com.kylecorry.trail_sense.tools.photo_maps.infrastructure.tiles.PhotoMapRegionLoader
1717
import kotlin.math.hypot
1818

@@ -80,17 +80,16 @@ class TileLoader {
8080
}
8181

8282
var hasChanges = false
83-
val parallel = ParallelCoroutineRunner()
8483

8584
val middleX = tileSources.keys.map { it.x }.average()
8685
val middleY = tileSources.keys.map { it.y }.average()
8786

8887
val sortedEntries = tileSources.entries
8988
.sortedBy { hypot(it.key.x - middleX, it.key.y - middleY) }
9089

91-
parallel.run(sortedEntries.toList()) { source ->
90+
Parallel.forEach(sortedEntries.toList()) { source ->
9291
if (tileCache.containsKey(source.key) && !alwaysReloadTiles) {
93-
return@run
92+
return@forEach
9493
}
9594

9695
val config = if (backgroundColor.alpha != 255) {
@@ -153,7 +152,7 @@ class TileLoader {
153152
synchronized(lock) {
154153
if (clearTileWhenNullResponse || image != null) {
155154
val old = tileCache[source.key]
156-
if (image == null){
155+
if (image == null) {
157156
tileCache -= source.key
158157
} else {
159158
tileCache += source.key to listOfNotNull(image)

0 commit comments

Comments
 (0)