Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

Commit

Permalink
Optimize AsyncSignal.invoke
Browse files Browse the repository at this point in the history
  • Loading branch information
soywiz committed Feb 24, 2019
1 parent b757d5b commit 0e43f7d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
7 changes: 3 additions & 4 deletions korio/src/commonMain/kotlin/com/soywiz/korio/async/Signal.kt
Expand Up @@ -32,11 +32,10 @@ class AsyncSignal<T>(val onRegister: () -> Unit = {}) { //: AsyncSequence<T> {
}

suspend operator fun invoke(value: T) {
val it = handlers.iterator()
while (it.hasNext()) {
val node = it.next()
if (node.once) it.remove()
handlers.fastIterateRemove { node ->
val remove = node.once
node.item(value)
remove
}
}

Expand Down
Expand Up @@ -21,3 +21,16 @@ internal inline fun <T> List<T>.fastForEachReverse(callback: (T) -> Unit) {
n++
}
}

internal inline fun <T> ArrayList<T>.fastIterateRemove(callback: (T) -> Boolean): ArrayList<T> {
var n = 0
var m = 0
while (n < size) {
if (m >= 0 && m != n) this[m] = this[n]
if (callback(this[n])) m--
n++
m++
}
while (this.size > m) this.removeAt(this.size - 1)
return this
}
@@ -0,0 +1,10 @@
package com.soywiz.korio.internal

import kotlin.test.*

class FastIterateRemoveTest {
@Test
fun test() {
assertEquals(listOf(1, 3, 5, 5, 3), arrayListOf(1, 2, 3, 4, 5, 5, 8, 8, 3).fastIterateRemove { it % 2 == 0 })
}
}

0 comments on commit 0e43f7d

Please sign in to comment.