Просмотр исходного кода

Use ConcurrentLinkedQueue instead of LockFreeLinkedList for ContactList

Him188 5 лет назад
Родитель
Сommit
0662e48fd2

+ 19 - 18
mirai-core-api/src/commonMain/kotlin/contact/ContactList.kt

@@ -12,8 +12,9 @@
 package net.mamoe.mirai.contact
 
 import net.mamoe.mirai.utils.LockFreeLinkedList
-import net.mamoe.mirai.utils.asSequence
-import kotlin.jvm.JvmField
+import net.mamoe.mirai.utils.MiraiInternalApi
+import net.mamoe.mirai.utils.PlannedRemoval
+import java.util.concurrent.ConcurrentLinkedQueue
 
 
 /**
@@ -23,27 +24,27 @@ import kotlin.jvm.JvmField
  */
 @Suppress("unused")
 public class ContactList<C : Contact>
-internal constructor(@JvmField internal val delegate: LockFreeLinkedList<C>) : Collection<C> {
+internal constructor(@JvmField @MiraiInternalApi public val delegate: ConcurrentLinkedQueue<C>) :
+    Collection<C> by delegate {
+    internal constructor(collection: Collection<C>) : this(ConcurrentLinkedQueue(collection))
+    internal constructor() : this(ConcurrentLinkedQueue())
 
-    public operator fun get(id: Long): C =
-        delegate.asSequence().firstOrNull { it.id == id } ?: throw NoSuchElementException("Contact id $id")
+    @PlannedRemoval("2.0-M2")
+    @Deprecated("Use get", ReplaceWith("get(id)"))
+    public fun getOrNull(id: Long): C? = get(id)
 
-    public fun getOrNull(id: Long): C? = delegate.getOrNull(id)
+    public operator fun get(id: Long): C? = delegate.firstOrNull { it.id == id }
+    public fun remove(id: Long): Boolean = delegate.removeAll { it.id == id }
+    public operator fun contains(id: Long): Boolean = get(id) != null
 
-    public override val size: Int get() = delegate.size
-    public override operator fun contains(element: C): Boolean = delegate.contains(element)
-    public operator fun contains(id: Long): Boolean = delegate.getOrNull(id) != null
-    public override fun containsAll(elements: Collection<C>): Boolean = elements.all { contains(it) }
-    public override fun isEmpty(): Boolean = delegate.isEmpty()
-
-    public override fun toString(): String =
-        delegate.asSequence().joinToString(separator = ", ", prefix = "ContactList(", postfix = ")")
-
-    public override fun iterator(): Iterator<C> {
-        return this.delegate.asSequence().iterator()
-    }
+    override fun toString(): String = delegate.joinToString(separator = ", ", prefix = "ContactList(", postfix = ")")
+    override fun equals(other: Any?): Boolean = other is ContactList<*> && delegate == other.delegate
+    override fun hashCode(): Int = delegate.hashCode()
 }
 
+@Deprecated("x", ReplaceWith("this.add(c)"))
+internal fun <C : Any?> ConcurrentLinkedQueue<C>.addLast(c: C): Boolean = this.add(c)
+
 /**
  * ID 列表的字符串表示.
  * 如:

+ 3 - 4
mirai-core/src/commonMain/kotlin/MiraiImpl.kt

@@ -672,7 +672,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
                 blackList = blackList
             ).sendWithoutExpect()
             @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
-            bot.friends.delegate.addLast(_lowLevelNewFriend(bot, object : FriendInfo {
+            bot.friends.delegate.add(_lowLevelNewFriend(bot, object : FriendInfo {
                 override val uin: Long get() = fromId
                 override val nick: String get() = fromNick
                 override val remark: String get() = ""
@@ -727,9 +727,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
         }
 
         if (accept ?: return@run)
-            groups[groupId].apply {
-                @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
-                members.delegate.addLast(newMember(object : MemberInfo {
+            groups[groupId]?.apply {
+                members.delegate.add(newMember(object : MemberInfo {
                     override val nameCard: String get() = ""
                     override val permission: MemberPermission get() = MemberPermission.MEMBER
                     override val specialTitle: String get() = ""

+ 2 - 2
mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt

@@ -63,7 +63,7 @@ internal abstract class QQAndroidBotBase constructor(
 
     inline val json get() = configuration.json
 
-    override val friends: ContactList<Friend> = ContactList(LockFreeLinkedList())
+    override val friends: ContactList<Friend> = ContactList()
 
     override lateinit var nick: String
 
@@ -99,7 +99,7 @@ internal abstract class QQAndroidBotBase constructor(
         return QQAndroidBotNetworkHandler(coroutineContext, this as QQAndroidBot)
     }
 
-    override val groups: ContactList<Group> = ContactList(LockFreeLinkedList())
+    override val groups: ContactList<Group> = ContactList()
 
     @JvmField
     val groupListModifyLock = Mutex()

+ 3 - 2
mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt

@@ -42,6 +42,7 @@ import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.data.*
 import net.mamoe.mirai.utils.*
 import java.io.InputStream
+import java.util.concurrent.ConcurrentLinkedQueue
 import kotlin.contracts.contract
 import kotlin.coroutines.CoroutineContext
 import kotlin.time.ExperimentalTime
@@ -97,7 +98,7 @@ internal class GroupImpl(
                 owner = member
             }
         }
-    }.toLockFreeLinkedList())
+    }.mapTo(ConcurrentLinkedQueue()) { it })
 
     internal var _name: String = groupInfo.name
     private var _announcement: String = groupInfo.memo
@@ -220,7 +221,7 @@ internal class GroupImpl(
             ).sendAndExpect()
             check(response.errorCode == 0) {
                 "Group.quit failed: $response".also {
-                    bot.groups.delegate.addLast(this@GroupImpl)
+                    bot.groups.delegate.add(this@GroupImpl)
                 }
             }
         }

+ 4 - 4
mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt

@@ -252,7 +252,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
             totalFriendCount = data.totalFriendCount
             data.friendList.forEach {
                 // atomic
-                bot.friends.delegate.addLast(
+                bot.friends.delegate.add(
                     FriendImpl(bot, bot.coroutineContext, it.friendUin, FriendInfoImpl(it))
                 ).also { currentFriendCount++ }
             }
@@ -268,7 +268,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
 
     suspend fun StTroopNum.reloadGroup() {
         retryCatching(3) {
-            bot.groups.delegate.addLast(
+            bot.groups.delegate.add(
                 GroupImpl(
                     bot = bot,
                     coroutineContext = bot.coroutineContext,
@@ -314,10 +314,10 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
 
         CancellationException("re-init").let { reInitCancellationException ->
             if (!initFriendOk) {
-                bot.friends.delegate.clear { it.cancel(reInitCancellationException) }
+                bot.friends.delegate.removeAll { it.cancel(reInitCancellationException); true }
             }
             if (!initGroupOk) {
-                bot.groups.delegate.clear { it.cancel(reInitCancellationException) }
+                bot.groups.delegate.removeAll { it.cancel(reInitCancellationException); true }
             }
         }
 

+ 3 - 5
mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt

@@ -141,9 +141,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
             return null
         }
 
-        return getNewGroup(Mirai.calculateGroupCodeByGroupUin(groupUin))?.apply {
-            groups.delegate.addLast(this)
-        }
+        return getNewGroup(Mirai.calculateGroupCodeByGroupUin(groupUin))?.apply { groups.delegate.add(this) }
     }
 
     @OptIn(FlowPreview::class)
@@ -237,11 +235,11 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                                     readByte().toInt().and(0xff)
                                 } == 0x83) {
                                 return@mapNotNull MemberJoinEvent.Invite(group.newMember(msg.getNewMemberInfo())
-                                    .also { group.members.delegate.addLast(it) })
+                                    .also { group.members.delegate.add(it) })
                             }
 
                             return@mapNotNull MemberJoinEvent.Active(group.newMember(msg.getNewMemberInfo())
-                                .also { group.members.delegate.addLast(it) })
+                                .also { group.members.delegate.add(it) })
                         }
                     }
 

+ 3 - 2
mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushTransMsg.kt

@@ -142,7 +142,7 @@ internal object OnlinePushPbPushTransMsg :
                                         get() = ""
                                 }).also { owner ->
                                     owner.checkIsMemberImpl().permission = MemberPermission.OWNER
-                                    group.members.delegate.addLast(owner)
+                                    group.members.delegate.add(owner)
                                     results.add(MemberJoinEvent.Retrieve(owner))
                                 }
                                 if (newOwner.permission != MemberPermission.OWNER) {
@@ -239,7 +239,8 @@ internal object OnlinePushPbPushTransMsg :
                         }
                         3, 0x83 -> bot.getGroupByUin(groupUin).let { group ->
                             if (target == bot.id) {
-                                return BotLeaveEvent.Kick(group.members[operator]).also {
+                                val member = group.members[operator] ?: return@let null
+                                return BotLeaveEvent.Kick(member).also {
                                     group.cancel(CancellationException("Being kicked"))
                                     bot.groups.delegate.remove(group)
                                 }

+ 1 - 1
mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.ReqPush.kt

@@ -462,7 +462,7 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
             override val nick: String get() = body.msgAddFrdNotify.fuinNick
             override val remark: String get() = ""
         })
-        bot.friends.delegate.addLast(new)
+        bot.friends.delegate.add(new)
         return@lambda528 sequenceOf(FriendAddEvent(new))
     },
     0xE2L to lambda528 { _ ->