summaryrefslogtreecommitdiff
path: root/platform-paper/src/test
diff options
context:
space:
mode:
authorSho Sakuma <me@m1sk9.dev>2026-08-03 00:47:45 +0900
committerSho Sakuma <me@m1sk9.dev>2026-08-05 00:42:23 +0900
commit8529d652372c5c85e9624e23c4fc1a67bebb00b2 (patch)
tree10811505b0f6d24f9d6bedaa7fac41bec5b8f92a /platform-paper/src/test
parent790dcf942a3acab1268d46e3fc22be25a4ee02d5 (diff)
downloadLunaticChat-8529d652372c5c85e9624e23c4fc1a67bebb00b2.tar.gz
LunaticChat-8529d652372c5c85e9624e23c4fc1a67bebb00b2.tar.bz2
LunaticChat-8529d652372c5c85e9624e23c4fc1a67bebb00b2.zip
perf: answer membership questions without copying member lists
isMember went through getChannelMembers, which copies a channel's whole member list defensively - to then run any{} over it and throw the copy away. getPlayerChannels did that once per channel, so asking "which channels is this player in" allocated an ArrayList per channel and scanned every one. It runs on join, and on every /lc channel join when a membership limit is configured. ChannelManager now answers both directly against the live lists: isMember scans in place, and channelIdsOf walks the membership map once. No copies, and getPlayerChannels no longer enumerates all channels separately to cross-reference them. Not done: the reviewed suggestion was a playerId -> channelIds reverse index for O(1) lookups. That means a second record of who is in what, updated by hand at five mutation sites, where drift shows up as a wrong membership answer rather than a crash. The allocation was the real cost here, and removing it does not introduce a fact stored twice. Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'platform-paper/src/test')
-rw-r--r--platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt25
1 files changed, 25 insertions, 0 deletions
diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt
index 28e1c82..02c4d1a 100644
--- a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt
+++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/chat/channel/ChannelMembershipManagerTest.kt
@@ -472,4 +472,29 @@ class ChannelMembershipManagerTest {
assertIs<ChannelPlayerBannedException>(result.exceptionOrNull())
}
+
+ @Test
+ fun `isMember should fail for a channel that does not exist`() {
+ val (membership, _, _) = createManagers()
+
+ val result = membership.isMember(createTestUUID(1), "no-such-ch")
+
+ assertIs<ChannelNotFoundException>(result.exceptionOrNull())
+ }
+
+ @Test
+ fun `getPlayerChannels should not report a deleted channel`() {
+ val ownerId = createTestUUID(1)
+ val playerId = createTestUUID(2)
+ val (membership, channelManager, _) = createManagers()
+ channelManager.createChannel(createTestChannel(id = "keep-ch", name = "Keep", ownerId = ownerId))
+ channelManager.createChannel(createTestChannel(id = "drop-ch", name = "Drop", ownerId = ownerId))
+ membership.joinChannel(playerId, "keep-ch")
+ channelManager.setPlayerChannel(playerId, null)
+ membership.joinChannel(playerId, "drop-ch")
+
+ channelManager.deleteChannel("drop-ch", ownerId)
+
+ assertEquals(listOf("keep-ch"), membership.getPlayerChannels(playerId).getOrThrow())
+ }
}