geforkt von Mirrors/Paper
6a54004bb4
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
106 Zeilen
4.8 KiB
Diff
106 Zeilen
4.8 KiB
Diff
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
|
|
|