@@ -6,7 +6,7 @@ Subject: [PATCH] Separate lookup locking from state access in UserCache
6
6
Prevent lookups from stalling simple state access/write calls
7
7
8
8
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
9
- index 95974d78196397136179f8d6acf1597c557e5a23..6349b33939909435120fdef5e506480108cfbfc1 100644
9
+ index d7eba4190110b92641664c827c6bc50f62d2ae15..534373a1e305942d63ffb0fc97ea3f165eca76b5 100644
10
10
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
11
11
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
12
12
@@ -62,6 +62,11 @@ public class GameProfileCache {
@@ -46,7 +46,18 @@ index 95974d78196397136179f8d6acf1597c557e5a23..6349b33939909435120fdef5e5064801
46
46
Calendar calendar = Calendar.getInstance();
47
47
48
48
calendar.setTime(new Date());
49
- @@ -142,8 +149,9 @@ public class GameProfileCache {
49
+ @@ -137,17 +144,20 @@ public class GameProfileCache {
50
+
51
+ // Paper start
52
+ @Nullable public GameProfile getProfileIfCached(String name) {
53
+ + try { this.stateLock.lock(); // Paper - allow better concurrency
54
+ GameProfileCache.GameProfileInfo entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT));
55
+ if (entry == null) {
56
+ return null;
57
+ }
58
+ entry.setLastAccess(this.getNextOperation());
59
+ return entry.getProfile();
60
+ + } finally { this.stateLock.unlock(); } // Paper - allow better concurrency
50
61
}
51
62
// Paper end
52
63
@@ -57,7 +68,7 @@ index 95974d78196397136179f8d6acf1597c557e5a23..6349b33939909435120fdef5e5064801
57
68
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1);
58
69
boolean flag = false;
59
70
60
- @@ -159 ,8 +167 ,12 @@ public class GameProfileCache {
71
+ @@ -163 ,8 +173 ,12 @@ public class GameProfileCache {
61
72
if (usercache_usercacheentry != null) {
62
73
usercache_usercacheentry.setLastAccess(this.getNextOperation());
63
74
optional = Optional.of(usercache_usercacheentry.getProfile());
@@ -70,37 +81,57 @@ index 95974d78196397136179f8d6acf1597c557e5a23..6349b33939909435120fdef5e5064801
70
81
if (optional.isPresent()) {
71
82
this.add((GameProfile) optional.get());
72
83
flag = false;
73
- @@ -172 ,6 +184 ,7 @@ public class GameProfileCache {
84
+ @@ -176 ,6 +190 ,7 @@ public class GameProfileCache {
74
85
}
75
86
76
87
return optional;
77
88
+ } finally { if (stateLocked) { this.stateLock.unlock(); } } // Paper - allow better concurrency
78
89
}
79
90
80
91
public void getAsync(String username, Consumer<Optional<GameProfile>> consumer) {
81
- @@ -198 ,6 +211 ,7 @@ public class GameProfileCache {
92
+ @@ -202 ,6 +217 ,7 @@ public class GameProfileCache {
82
93
}
83
94
84
95
public Optional<GameProfile> get(UUID uuid) {
85
96
+ try { this.stateLock.lock(); // Paper - allow better concurrency
86
97
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByUUID.get(uuid);
87
98
88
99
if (usercache_usercacheentry == null) {
89
- @@ -206 ,6 +220 ,7 @@ public class GameProfileCache {
100
+ @@ -210 ,6 +226 ,7 @@ public class GameProfileCache {
90
101
usercache_usercacheentry.setLastAccess(this.getNextOperation());
91
102
return Optional.of(usercache_usercacheentry.getProfile());
92
103
}
93
104
+ } finally { this.stateLock.unlock(); } // Paper - allow better concurrency
94
105
}
95
106
96
107
public void setExecutor(Executor executor) {
97
- @@ -326,7 +341,9 @@ public class GameProfileCache {
108
+ @@ -290,7 +307,7 @@ public class GameProfileCache {
109
+ JsonArray jsonarray = new JsonArray();
110
+ DateFormat dateformat = GameProfileCache.createDateFormat();
111
+
112
+ - this.getTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot
113
+ + this.listTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot // Paper - allow better concurrency
114
+ jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat));
115
+ });
116
+ String s = this.gson.toJson(jsonarray);
117
+ @@ -330,8 +347,19 @@ public class GameProfileCache {
98
118
}
99
119
100
120
private Stream<GameProfileCache.GameProfileInfo> getTopMRUProfiles(int limit) {
101
- + try { this.stateLock.lock(); // Paper - allow better concurrency
102
- return ImmutableList.copyOf(this.profilesByUUID.values()).stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit((long) limit);
103
- + } finally { this.stateLock.unlock(); } // Paper - allow better concurrency
121
+ - return ImmutableList.copyOf(this.profilesByUUID.values()).stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit((long) limit);
122
+ + // Paper start - allow better concurrency
123
+ + return this.listTopMRUProfiles(limit).stream();
124
+ + }
125
+ +
126
+ + private List<GameProfileCache.GameProfileInfo> listTopMRUProfiles(int limit) {
127
+ + try {
128
+ + this.stateLock.lock();
129
+ + return this.profilesByUUID.values().stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit(limit).toList();
130
+ + } finally {
131
+ + this.stateLock.unlock();
132
+ + }
104
133
}
134
+ + // Paper end
105
135
106
136
private static JsonElement writeGameProfile(GameProfileCache.GameProfileInfo entry, DateFormat dateFormat) {
137
+ JsonObject jsonobject = new JsonObject();
0 commit comments