diff options
| author | Sho Sakuma <me@m1sk9.dev> | 2026-08-03 00:47:45 +0900 |
|---|---|---|
| committer | Sho Sakuma <me@m1sk9.dev> | 2026-08-05 00:42:23 +0900 |
| commit | 8529d652372c5c85e9624e23c4fc1a67bebb00b2 (patch) | |
| tree | 10811505b0f6d24f9d6bedaa7fac41bec5b8f92a /platform-paper/src/test | |
| parent | 790dcf942a3acab1268d46e3fc22be25a4ee02d5 (diff) | |
| download | LunaticChat-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.kt | 25 |
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()) + } } |
