From ec115e83b16568d2f782c7b3db0fdd5f79686cd1 Mon Sep 17 00:00:00 2001 From: Him188 Date: Wed, 12 Feb 2020 20:00:52 +0800 Subject: [PATCH] Add `Iterable.toLockFreeLinkedList()` and `Sequence.toLockFreeLinkedList()` --- .../utils/LockFreeLinkedList.kt | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) 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 d950d2979..c6fd8ed7c 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 @@ -68,6 +68,20 @@ fun LockFreeLinkedList.asSequence(): Sequence { } } +/** + * 构建链表结构然后转为 [LockFreeLinkedList] + */ +fun Iterable.toLockFreeLinkedList(): LockFreeLinkedList { + return LockFreeLinkedList().apply { addLastAll(this@toLockFreeLinkedList) } +} + +/** + * 构建链表结构然后转为 [LockFreeLinkedList] + */ +fun Sequence.toLockFreeLinkedList(): LockFreeLinkedList { + return LockFreeLinkedList().apply { addLastAll(this@toLockFreeLinkedList) } +} + /** * Implementation of lock-free LinkedList. * @@ -111,8 +125,10 @@ open class LockFreeLinkedList { } open fun addLast(element: E) { - val node = element.asNode(tail) + addLastNode(element.asNode(tail)) + } + private fun addLastNode(node: Node) { while (true) { val tail = head.iterateBeforeFirst { it === tail } // find the last node. if (tail.nextNodeRef.compareAndSet(this.tail, node)) { // ensure the last node is the last node @@ -121,6 +137,36 @@ open class LockFreeLinkedList { } } + /** + * 先把元素建立好链表, 再加入到 list. + */ + @Suppress("DuplicatedCode") + open fun addLastAll(iterable: Iterable) { + var currentNode: Node? = null + iterable.forEach { + val nextNode = it.asNode(tail) + currentNode?.nextNode = nextNode + currentNode = nextNode + } + addLastNode(currentNode ?: error("iterable is empty")) + } + + /** + * 先把元素建立好链表, 再加入到 list. + */ + @Suppress("DuplicatedCode") + open fun addLastAll(iterable: Sequence) { + var currentNode: Node? = null + iterable.forEach { + val nextNode = it.asNode(tail) + if (currentNode != null) { // do not use `?.` because atomicfu cannot transform properly: IllegalArgumentException: null passed + currentNode!!.nextNodeRef.value = nextNode + } + currentNode = nextNode + } + addLastNode(currentNode ?: error("iterable is empty")) + } + open operator fun plusAssign(element: E) = this.addLast(element) /**