mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-30 16:19:03 +01:00
Reduce thread synchronization in MetadataStoreBase
Use ConcurrentHashMap to allow thread-safe access methods and very limited synchronized portions to allow much higher concurrency in MetadataStore as well as far less locking, especially on reads
This commit is contained in:
parent
002a6a15e5
commit
fc77a4d2d3
1 changed files with 16 additions and 12 deletions
|
@ -12,7 +12,7 @@ import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class MetadataStoreBase<T> {
|
public abstract class MetadataStoreBase<T> {
|
||||||
private Map<String, Map<Plugin, MetadataValue>> metadataMap = new HashMap<String, Map<Plugin, MetadataValue>>();
|
private Map<String, Map<Plugin, MetadataValue>> metadataMap = new java.util.concurrent.ConcurrentHashMap<String, Map<Plugin, MetadataValue>>(); // Paper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a metadata value to an object. Each metadata value is owned by a
|
* Adds a metadata value to an object. Each metadata value is owned by a
|
||||||
|
@ -46,8 +46,10 @@ public abstract class MetadataStoreBase<T> {
|
||||||
entry = new WeakHashMap<Plugin, MetadataValue>(1);
|
entry = new WeakHashMap<Plugin, MetadataValue>(1);
|
||||||
metadataMap.put(key, entry);
|
metadataMap.put(key, entry);
|
||||||
}
|
}
|
||||||
|
synchronized (entry) {
|
||||||
entry.put(owningPlugin, newMetadataValue);
|
entry.put(owningPlugin, newMetadataValue);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all metadata values attached to an object. If multiple
|
* Returns all metadata values attached to an object. If multiple
|
||||||
|
@ -60,10 +62,11 @@ public abstract class MetadataStoreBase<T> {
|
||||||
* @see MetadataStore#getMetadata(Object, String)
|
* @see MetadataStore#getMetadata(Object, String)
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public synchronized List<MetadataValue> getMetadata(@NotNull T subject, @NotNull String metadataKey) {
|
public List<MetadataValue> getMetadata(@NotNull T subject, @NotNull String metadataKey) { // Paper
|
||||||
String key = disambiguate(subject, metadataKey);
|
String key = disambiguate(subject, metadataKey);
|
||||||
if (metadataMap.containsKey(key)) {
|
Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
||||||
Collection<MetadataValue> values = metadataMap.get(key).values();
|
if (entry != null) {
|
||||||
|
Collection<MetadataValue> values = entry.values();
|
||||||
return Collections.unmodifiableList(new ArrayList<MetadataValue>(values));
|
return Collections.unmodifiableList(new ArrayList<MetadataValue>(values));
|
||||||
} else {
|
} else {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -78,7 +81,7 @@ public abstract class MetadataStoreBase<T> {
|
||||||
* @param metadataKey the unique metadata key being queried.
|
* @param metadataKey the unique metadata key being queried.
|
||||||
* @return the existence of the metadataKey within subject.
|
* @return the existence of the metadataKey within subject.
|
||||||
*/
|
*/
|
||||||
public synchronized boolean hasMetadata(@NotNull T subject, @NotNull String metadataKey) {
|
public boolean hasMetadata(@NotNull T subject, @NotNull String metadataKey) { // Paper
|
||||||
String key = disambiguate(subject, metadataKey);
|
String key = disambiguate(subject, metadataKey);
|
||||||
return metadataMap.containsKey(key);
|
return metadataMap.containsKey(key);
|
||||||
}
|
}
|
||||||
|
@ -94,19 +97,20 @@ public abstract class MetadataStoreBase<T> {
|
||||||
* @see MetadataStore#removeMetadata(Object, String,
|
* @see MetadataStore#removeMetadata(Object, String,
|
||||||
* org.bukkit.plugin.Plugin)
|
* org.bukkit.plugin.Plugin)
|
||||||
*/
|
*/
|
||||||
public synchronized void removeMetadata(@NotNull T subject, @NotNull String metadataKey, @NotNull Plugin owningPlugin) {
|
public void removeMetadata(@NotNull T subject, @NotNull String metadataKey, @NotNull Plugin owningPlugin) { // Paper
|
||||||
Preconditions.checkArgument(owningPlugin != null, "Plugin cannot be null");
|
Preconditions.checkArgument(owningPlugin != null, "Plugin cannot be null");
|
||||||
String key = disambiguate(subject, metadataKey);
|
String key = disambiguate(subject, metadataKey);
|
||||||
Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
synchronized (entry) {
|
||||||
entry.remove(owningPlugin);
|
entry.remove(owningPlugin);
|
||||||
if (entry.isEmpty()) {
|
if (entry.isEmpty()) {
|
||||||
metadataMap.remove(key);
|
metadataMap.remove(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidates all metadata in the metadata store that originates from the
|
* Invalidates all metadata in the metadata store that originates from the
|
||||||
|
@ -117,7 +121,7 @@ public abstract class MetadataStoreBase<T> {
|
||||||
* @throws IllegalArgumentException If plugin is null
|
* @throws IllegalArgumentException If plugin is null
|
||||||
* @see MetadataStore#invalidateAll(org.bukkit.plugin.Plugin)
|
* @see MetadataStore#invalidateAll(org.bukkit.plugin.Plugin)
|
||||||
*/
|
*/
|
||||||
public synchronized void invalidateAll(@NotNull Plugin owningPlugin) {
|
public void invalidateAll(@NotNull Plugin owningPlugin) { // Paper
|
||||||
Preconditions.checkArgument(owningPlugin != null, "Plugin cannot be null");
|
Preconditions.checkArgument(owningPlugin != null, "Plugin cannot be null");
|
||||||
for (Map<Plugin, MetadataValue> values : metadataMap.values()) {
|
for (Map<Plugin, MetadataValue> values : metadataMap.values()) {
|
||||||
if (values.containsKey(owningPlugin)) {
|
if (values.containsKey(owningPlugin)) {
|
||||||
|
|
Loading…
Reference in a new issue