Skip to content

Commit db0a5e2

Browse files
perf(render): reuse the viewer membership buffer (#84)
Co-authored-by: Arbousier1 <elderli@foxmail.com>
1 parent 0ebc5fc commit db0a5e2

1 file changed

Lines changed: 49 additions & 15 deletions

File tree

src/main/java/top/ellan/mahjong/table/render/TableRenderSnapshotFactory.java

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,40 @@
44
import top.ellan.mahjong.render.TableRenderSubject;
55
import top.ellan.mahjong.render.snapshot.TableRenderSnapshot;
66
import top.ellan.mahjong.render.snapshot.TableSeatRenderSnapshot;
7+
import java.util.Collections;
78
import java.util.Comparator;
89
import java.util.EnumMap;
910
import java.util.HashMap;
10-
import java.util.HashSet;
1111
import java.util.List;
1212
import java.util.Map;
1313
import java.util.Objects;
14-
import java.util.Set;
1514
import java.util.UUID;
1615
import org.bukkit.Location;
1716
import org.bukkit.entity.Player;
1817

1918
public final class TableRenderSnapshotFactory {
19+
private static final Comparator<SerializedViewerId> SERIALIZED_VIEWER_ID_COMPARATOR =
20+
Comparator.comparing(SerializedViewerId::serializedId);
21+
2022
public TableRenderSnapshot create(TableRenderSubject session, long version, long cancellationNonce) {
2123
Location tableCenter = session.center();
2224
boolean started = session.isStarted();
2325
List<SerializedViewerId> serializedOnlineViewerIds = session.viewers().stream()
2426
.map(Player::getUniqueId)
2527
.distinct()
2628
.map(viewerId -> new SerializedViewerId(viewerId, viewerId.toString()))
27-
.sorted(Comparator.comparing(SerializedViewerId::serializedId))
29+
.sorted(SERIALIZED_VIEWER_ID_COMPARATOR)
2830
.toList();
2931
List<UUID> onlineViewerIds = serializedOnlineViewerIds.stream()
3032
.map(SerializedViewerId::id)
3133
.toList();
32-
Set<UUID> onlineViewerIdSet = new HashSet<>(onlineViewerIds);
34+
Map<UUID, SerializedViewerId> serializedOnlineViewersById = new HashMap<>(
35+
Math.max(16, (int) (serializedOnlineViewerIds.size() / 0.75F) + 1)
36+
);
37+
for (SerializedViewerId viewer : serializedOnlineViewerIds) {
38+
serializedOnlineViewersById.put(viewer.id(), viewer);
39+
}
40+
StringBuilder viewerMembershipBuffer = this.viewerMembershipBuffer(serializedOnlineViewerIds);
3341
SeatWind[] seatWinds = SeatWind.values();
3442
EnumMap<SeatWind, UUID> seatPlayerIds = new EnumMap<>(SeatWind.class);
3543
for (SeatWind wind : seatWinds) {
@@ -38,13 +46,28 @@ public TableRenderSnapshot create(TableRenderSubject session, long version, long
3846
Map<UUID, String> viewerMembershipSignatures = new HashMap<>();
3947
Map<UUID, List<UUID>> viewerIdsExcluding = new HashMap<>();
4048
for (UUID playerId : seatPlayerIds.values()) {
41-
if (viewerMembershipSignatures.containsKey(playerId)
42-
|| playerId != null && !onlineViewerIdSet.contains(playerId)) {
49+
if (viewerMembershipSignatures.containsKey(playerId)) {
50+
continue;
51+
}
52+
SerializedViewerId excludedViewer = playerId == null
53+
? null
54+
: serializedOnlineViewersById.get(playerId);
55+
if (playerId != null && excludedViewer == null) {
4356
continue;
4457
}
4558
viewerMembershipSignatures.put(
4659
playerId,
47-
this.viewerMembershipSignature(serializedOnlineViewerIds, playerId)
60+
excludedViewer == null
61+
? viewerMembershipBuffer.toString()
62+
: this.viewerMembershipSignature(
63+
viewerMembershipBuffer,
64+
excludedViewer,
65+
Collections.binarySearch(
66+
serializedOnlineViewerIds,
67+
excludedViewer,
68+
SERIALIZED_VIEWER_ID_COMPARATOR
69+
)
70+
)
4871
);
4972
viewerIdsExcluding.put(
5073
playerId,
@@ -59,7 +82,7 @@ public TableRenderSnapshot create(TableRenderSubject session, long version, long
5982
session,
6083
wind,
6184
seatPlayerIds.get(wind),
62-
onlineViewerIdSet,
85+
serializedOnlineViewersById,
6386
viewerMembershipSignatures,
6487
viewerIdsExcluding
6588
)
@@ -131,7 +154,7 @@ private TableSeatRenderSnapshot captureSeatSnapshot(
131154
TableRenderSubject session,
132155
SeatWind wind,
133156
UUID playerId,
134-
Set<UUID> onlineViewerIdSet,
157+
Map<UUID, SerializedViewerId> serializedOnlineViewersById,
135158
Map<UUID, String> viewerMembershipSignatures,
136159
Map<UUID, List<UUID>> viewerIdsExcluding
137160
) {
@@ -145,7 +168,7 @@ private TableSeatRenderSnapshot captureSeatSnapshot(
145168
occupied && session.isRiichi(playerId),
146169
occupied && session.isReady(playerId),
147170
occupied && session.isQueuedToLeave(playerId),
148-
occupied && onlineViewerIdSet.contains(playerId),
171+
occupied && serializedOnlineViewersById.containsKey(playerId),
149172
viewerMembershipSignatures.getOrDefault(playerId, ""),
150173
occupied ? session.selectedHandTileIndex(playerId) : -1,
151174
occupied ? session.selectedHandTileIndices(playerId) : List.of(),
@@ -160,14 +183,25 @@ private TableSeatRenderSnapshot captureSeatSnapshot(
160183
);
161184
}
162185

163-
private String viewerMembershipSignature(List<SerializedViewerId> onlineViewerIds, UUID excludedPlayerId) {
186+
private StringBuilder viewerMembershipBuffer(List<SerializedViewerId> onlineViewerIds) {
164187
StringBuilder builder = new StringBuilder(onlineViewerIds.size() * 36);
165188
for (SerializedViewerId viewer : onlineViewerIds) {
166-
if (!viewer.id().equals(excludedPlayerId)) {
167-
builder.append(viewer.serializedId());
168-
}
189+
builder.append(viewer.serializedId());
169190
}
170-
return builder.toString();
191+
return builder;
192+
}
193+
194+
private String viewerMembershipSignature(
195+
StringBuilder viewerMembershipBuffer,
196+
SerializedViewerId excludedViewer,
197+
int excludedViewerIndex
198+
) {
199+
String serializedId = excludedViewer.serializedId();
200+
int start = excludedViewerIndex * serializedId.length();
201+
viewerMembershipBuffer.delete(start, start + serializedId.length());
202+
String signature = viewerMembershipBuffer.toString();
203+
viewerMembershipBuffer.insert(start, serializedId);
204+
return signature;
171205
}
172206

173207
private List<UUID> viewerIdsExcluding(List<UUID> onlineViewerIds, UUID excludedPlayerId) {

0 commit comments

Comments
 (0)