diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt index 409b05fe5..adae98c1e 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt @@ -51,15 +51,26 @@ fun LockFreeLinkedList.toMutableSet(): MutableSet { /** * Builds a [Sequence] containing all the elements in [this] in the same order. * - * Note that the sequence is dynamic, that is, elements are yielded atomically only when it is required + * Note that the sequence is dynamic */ @MiraiInternalAPI fun LockFreeLinkedList.asSequence(): Sequence { - return sequence { - forEach { - yield(it) + return generateSequence(head) { current: LockFreeLinkedListNode -> + current.nextValidNode(until = tail).takeIf { it != tail } + }.drop(1) // drop head, should be dropped lazily + .map { it.nodeValue } +} + +@OptIn(MiraiInternalAPI::class) +internal fun LockFreeLinkedListNode.nextValidNode(until: LockFreeLinkedListNode): LockFreeLinkedListNode { + var node: LockFreeLinkedListNode = this.nextNode + while (node != until) { + if (node.isValidElementNode()) { + return node } + node = node.nextNode } + return node } @MiraiInternalAPI diff --git a/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt b/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt index 2009c8d3a..285a77316 100644 --- a/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt +++ b/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt @@ -20,6 +20,7 @@ import kotlin.test.assertFalse import kotlin.test.assertTrue @Suppress("UnusedEquals") +@OptIn(MiraiInternalAPI::class) @MiraiExperimentalAPI internal class LockFreeLinkedListTest { @Test @@ -263,7 +264,7 @@ internal class LockFreeLinkedListTest { */ } -@OptIn(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class, MiraiInternalAPI::class) @MiraiExperimentalAPI internal suspend inline fun > E.concurrentDo( numberOfCoroutines: Int,