Skip to content

Commit ef9ec5e

Browse files
committed
perf(render): isolate the viewer lookup fast path
1 parent 14c879c commit ef9ec5e

3 files changed

Lines changed: 40 additions & 247 deletions

File tree

src/main/java/top/ellan/mahjong/render/display/ClientInteractionProxyRegistry.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,6 @@ public static String tableIdFor(int entityId, UUID viewerId) {
2626
return owner != null && viewerId.equals(owner.viewerId()) ? owner.tableId() : null;
2727
}
2828

29-
public static boolean isOwnedBy(int entityId, UUID viewerId, String tableId) {
30-
if (viewerId == null || tableId == null) {
31-
return false;
32-
}
33-
ProxyOwner owner = OWNERS.get(entityId);
34-
return owner != null && owner.matches(viewerId, tableId);
35-
}
36-
3729
public static void unregister(int entityId, UUID viewerId, String tableId) {
3830
if (viewerId == null || tableId == null) {
3931
return;
@@ -73,8 +65,5 @@ public static void clear() {
7365
}
7466

7567
private record ProxyOwner(UUID viewerId, String tableId) {
76-
private boolean matches(UUID expectedViewerId, String expectedTableId) {
77-
return expectedViewerId.equals(this.viewerId) && expectedTableId.equals(this.tableId);
78-
}
7968
}
8069
}

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

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,16 @@ final class SparrowRayInteractionProxyCoordinator {
3636
private static final Backend DEFAULT_BACKEND = new SparrowBackend();
3737

3838
private final TableSessionContext session;
39-
private final String tableId;
4039
private final Backend backend;
4140
private final Map<String, Map<UUID, ActiveProxies>> regions = new LinkedHashMap<>();
4241
private final AtomicBoolean warningLogged = new AtomicBoolean();
43-
private int entityCount;
4442

4543
SparrowRayInteractionProxyCoordinator(TableSessionContext session) {
4644
this(session, DEFAULT_BACKEND);
4745
}
4846

4947
SparrowRayInteractionProxyCoordinator(TableSessionContext session, Backend backend) {
5048
this.session = session;
51-
this.tableId = session == null ? null : session.id();
5249
this.backend = backend;
5350
}
5451

@@ -90,14 +87,9 @@ synchronized void replace(
9087
continue;
9188
}
9289
List<InteractionGeometry> geometry = interactionGeometry(interactions);
93-
List<ClientProxy> proxies = List.copyOf(this.backend.create(viewer, interactions));
90+
List<ClientProxy> proxies = this.backend.create(viewer, interactions);
9491
if (!proxies.isEmpty()) {
95-
ActiveProxies created = new ActiveProxies(
96-
viewer,
97-
proxies,
98-
geometry,
99-
proxies.get(0).entityId()
100-
);
92+
ActiveProxies created = new ActiveProxies(viewer, List.copyOf(proxies), geometry);
10193
next.put(viewerId, created);
10294
pendingSpawns.add(new PendingSpawn(viewerId, created));
10395
}
@@ -114,21 +106,18 @@ synchronized void replace(
114106
this.removeActive(viewerId, active);
115107
}
116108
});
117-
int previousCount = proxyCount(previous);
118109
if (next.isEmpty()) {
119110
this.regions.remove(regionKey);
120-
this.entityCount -= previousCount;
121111
return;
122112
}
123113

124114
Map<UUID, ActiveProxies> immutableNext = Map.copyOf(next);
125115
this.regions.put(regionKey, immutableNext);
126-
this.entityCount += proxyCount(immutableNext) - previousCount;
127116
for (PendingSpawn pending : pendingSpawns) {
128117
UUID viewerId = pending.viewerId();
129118
ActiveProxies active = pending.active();
130-
for (int index = 0; index < active.proxies().size(); index++) {
131-
ClientInteractionProxyRegistry.register(active.entityId(index), viewerId, this.tableId);
119+
for (ClientProxy proxy : active.proxies()) {
120+
ClientInteractionProxyRegistry.register(proxy.entityId(), viewerId, this.session.id());
132121
}
133122
try {
134123
this.session.runForViewer(
@@ -172,15 +161,15 @@ private boolean canReuse(
172161
ActiveProxies active,
173162
List<DisplayInteractionRayRegistry.RayInteraction> interactions
174163
) {
175-
if (active == null || active.proxies().isEmpty() || !sameGeometry(active.geometry(), interactions)) {
164+
if (active == null
165+
|| !sameGeometry(active.geometry(), interactions)
166+
|| active.proxies().isEmpty()) {
176167
return false;
177168
}
178-
return this.hasOwnership(viewerId, active);
179-
}
180-
181-
private boolean hasOwnership(UUID viewerId, ActiveProxies active) {
182-
for (int index = 0; index < active.proxies().size(); index++) {
183-
if (!ClientInteractionProxyRegistry.isOwnedBy(active.entityId(index), viewerId, this.tableId)) {
169+
for (ClientProxy proxy : active.proxies()) {
170+
if (!this.session.id().equals(
171+
ClientInteractionProxyRegistry.tableIdFor(proxy.entityId(), viewerId)
172+
)) {
184173
return false;
185174
}
186175
}
@@ -233,9 +222,16 @@ synchronized boolean isCurrent(String regionKey, Set<UUID> expectedOwners) {
233222
continue;
234223
}
235224
ActiveProxies active = activeByViewer == null ? null : activeByViewer.get(ownerId);
236-
if (active == null || active.proxies().isEmpty() || !this.hasOwnership(ownerId, active)) {
225+
if (active == null || active.proxies().isEmpty()) {
237226
return false;
238227
}
228+
for (ClientProxy proxy : active.proxies()) {
229+
if (!this.session.id().equals(
230+
ClientInteractionProxyRegistry.tableIdFor(proxy.entityId(), ownerId)
231+
)) {
232+
return false;
233+
}
234+
}
239235
}
240236
return true;
241237
}
@@ -245,7 +241,6 @@ synchronized void remove(String regionKey) {
245241
if (removed == null) {
246242
return;
247243
}
248-
this.entityCount -= proxyCount(removed);
249244
removed.forEach(this::removeActive);
250245
}
251246

@@ -265,7 +260,6 @@ synchronized void removeViewer(UUID viewerId) {
265260
} else {
266261
this.regions.put(regionKey, Map.copyOf(remaining));
267262
}
268-
this.entityCount -= removed.proxies().size();
269263
this.removeActive(viewerId, removed);
270264
}
271265
}
@@ -274,15 +268,13 @@ synchronized void clear() {
274268
for (String regionKey : List.copyOf(this.regions.keySet())) {
275269
this.remove(regionKey);
276270
}
277-
this.entityCount = 0;
278-
ClientInteractionProxyRegistry.clearTable(this.tableId);
271+
ClientInteractionProxyRegistry.clearTable(this.session.id());
279272
}
280273

281274
synchronized void shutdown() {
282275
Map<String, Map<UUID, ActiveProxies>> activeRegions = Map.copyOf(this.regions);
283276
this.regions.clear();
284-
this.entityCount = 0;
285-
ClientInteractionProxyRegistry.clearTable(this.tableId);
277+
ClientInteractionProxyRegistry.clearTable(this.session.id());
286278
activeRegions.values().forEach(activeByViewer -> activeByViewer.forEach((viewerId, active) -> {
287279
if (active.viewer().isOnline()) {
288280
this.destroyQuietly(active.viewer(), active.proxies());
@@ -291,13 +283,11 @@ synchronized void shutdown() {
291283
}
292284

293285
synchronized int entityCount() {
294-
return this.entityCount;
295-
}
296-
297-
private static int proxyCount(Map<UUID, ActiveProxies> activeByViewer) {
298286
int count = 0;
299-
for (ActiveProxies active : activeByViewer.values()) {
300-
count += active.proxies().size();
287+
for (Map<UUID, ActiveProxies> activeByViewer : this.regions.values()) {
288+
for (ActiveProxies active : activeByViewer.values()) {
289+
count += active.proxies().size();
290+
}
301291
}
302292
return count;
303293
}
@@ -322,14 +312,14 @@ private void spawnIfCurrent(String regionKey, UUID viewerId, ActiveProxies expec
322312
}
323313
}
324314

325-
private void unregister(UUID viewerId, ActiveProxies active) {
326-
for (int index = 0; index < active.proxies().size(); index++) {
327-
ClientInteractionProxyRegistry.unregister(active.entityId(index), viewerId, this.tableId);
315+
private void unregister(UUID viewerId, List<ClientProxy> proxies) {
316+
for (ClientProxy proxy : proxies) {
317+
ClientInteractionProxyRegistry.unregister(proxy.entityId(), viewerId, this.session.id());
328318
}
329319
}
330320

331321
private void removeActive(UUID viewerId, ActiveProxies active) {
332-
this.unregister(viewerId, active);
322+
this.unregister(viewerId, active.proxies());
333323
if (!active.viewer().isOnline()) {
334324
return;
335325
}
@@ -385,12 +375,8 @@ interface ClientProxy {
385375
private record ActiveProxies(
386376
Player viewer,
387377
List<ClientProxy> proxies,
388-
List<InteractionGeometry> geometry,
389-
int firstEntityId
378+
List<InteractionGeometry> geometry
390379
) {
391-
private int entityId(int index) {
392-
return index == 0 ? this.firstEntityId : this.proxies.get(index).entityId();
393-
}
394380
}
395381

396382
private record PendingSpawn(UUID viewerId, ActiveProxies active) {

0 commit comments

Comments
 (0)