mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-15 07:01:36 +08: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
c09424fd33
commit
6a54004bb4
@ -0,0 +1,105 @@
|
||||
From d8fc6b74a4f590473b3abad8958d0e929df6074f Mon Sep 17 00:00:00 2001
|
||||
From: crast <contact@jamescrasta.com>
|
||||
Date: Sat, 1 Jun 2013 13:52:30 -0600
|
||||
Subject: [PATCH] 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
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
index 093c144..64c0f0a 100644
|
||||
--- a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
+++ b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
@@ -4,9 +4,10 @@ import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
+import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
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 ConcurrentHashMap<String, Map<Plugin, MetadataValue>>();
|
||||
|
||||
/**
|
||||
* Adds a metadata value to an object. Each metadata value is owned by a
|
||||
@@ -30,7 +31,7 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @throws IllegalArgumentException If value is null, or the owning plugin
|
||||
* is null
|
||||
*/
|
||||
- public synchronized void setMetadata(T subject, String metadataKey, MetadataValue newMetadataValue) {
|
||||
+ public void setMetadata(T subject, String metadataKey, MetadataValue newMetadataValue) {
|
||||
Validate.notNull(newMetadataValue, "Value cannot be null");
|
||||
Plugin owningPlugin = newMetadataValue.getOwningPlugin();
|
||||
Validate.notNull(owningPlugin, "Plugin cannot be null");
|
||||
@@ -40,7 +41,9 @@ public abstract class MetadataStoreBase<T> {
|
||||
entry = new WeakHashMap<Plugin, MetadataValue>(1);
|
||||
metadataMap.put(key, entry);
|
||||
}
|
||||
- entry.put(owningPlugin, newMetadataValue);
|
||||
+ synchronized (entry) {
|
||||
+ entry.put(owningPlugin, newMetadataValue);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,10 +56,11 @@ public abstract class MetadataStoreBase<T> {
|
||||
* requested value.
|
||||
* @see MetadataStore#getMetadata(Object, String)
|
||||
*/
|
||||
- public synchronized List<MetadataValue> getMetadata(T subject, String metadataKey) {
|
||||
+ public List<MetadataValue> getMetadata(T subject, String metadataKey) {
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
- if (metadataMap.containsKey(key)) {
|
||||
- Collection<MetadataValue> values = metadataMap.get(key).values();
|
||||
+ Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
||||
+ if (entry != null) {
|
||||
+ Collection<MetadataValue> values = entry.values();
|
||||
return Collections.unmodifiableList(new ArrayList<MetadataValue>(values));
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
@@ -71,7 +75,7 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @param metadataKey the unique metadata key being queried.
|
||||
* @return the existence of the metadataKey within subject.
|
||||
*/
|
||||
- public synchronized boolean hasMetadata(T subject, String metadataKey) {
|
||||
+ public boolean hasMetadata(T subject, String metadataKey) {
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
return metadataMap.containsKey(key);
|
||||
}
|
||||
@@ -87,17 +91,18 @@ public abstract class MetadataStoreBase<T> {
|
||||
* org.bukkit.plugin.Plugin)
|
||||
* @throws IllegalArgumentException If plugin is null
|
||||
*/
|
||||
- public synchronized void removeMetadata(T subject, String metadataKey, Plugin owningPlugin) {
|
||||
+ public void removeMetadata(T subject, String metadataKey, Plugin owningPlugin) {
|
||||
Validate.notNull(owningPlugin, "Plugin cannot be null");
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
-
|
||||
- entry.remove(owningPlugin);
|
||||
- if (entry.isEmpty()) {
|
||||
- metadataMap.remove(key);
|
||||
+ synchronized (entry) {
|
||||
+ entry.remove(owningPlugin);
|
||||
+ if (entry.isEmpty()) {
|
||||
+ metadataMap.remove(key);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +115,7 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @see MetadataStore#invalidateAll(org.bukkit.plugin.Plugin)
|
||||
* @throws IllegalArgumentException If plugin is null
|
||||
*/
|
||||
- public synchronized void invalidateAll(Plugin owningPlugin) {
|
||||
+ public void invalidateAll(Plugin owningPlugin) {
|
||||
Validate.notNull(owningPlugin, "Plugin cannot be null");
|
||||
for (Map<Plugin, MetadataValue> values : metadataMap.values()) {
|
||||
if (values.containsKey(owningPlugin)) {
|
||||
--
|
||||
2.7.4
|
||||
|
Loading…
Reference in New Issue
Block a user