mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-30 16:19:03 +01:00
97c1f9402f
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
103 lines
No EOL
4.8 KiB
Diff
103 lines
No EOL
4.8 KiB
Diff
From 0000000000000000000000000000000000000000 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
|
+++ b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
|
@@ -0,0 +0,0 @@ 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
|
|
@@ -0,0 +0,0 @@ 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");
|
|
@@ -0,0 +0,0 @@ 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);
|
|
+ }
|
|
}
|
|
|
|
/**
|
|
@@ -0,0 +0,0 @@ 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();
|
|
@@ -0,0 +0,0 @@ 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);
|
|
}
|
|
@@ -0,0 +0,0 @@ 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);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -0,0 +0,0 @@ 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)) {
|
|
--
|