mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 13:45:36 +01:00
Fixes #316
This commit is contained in:
parent
c39f92248f
commit
9de370ebc8
@ -145,8 +145,7 @@ public class Settings extends Config {
|
||||
public static int CHUNK_WAIT_MS = 1000;
|
||||
@Comment("Delete history on disk after a number of days")
|
||||
public static int DELETE_AFTER_DAYS = 7;
|
||||
@Comment("Delete history in memory on logout (does not effect disk) (BROKEN, USE DISK INSTEAD)")
|
||||
@Final // Deprecated
|
||||
@Comment("Delete history in memory on logout (does not effect disk)")
|
||||
public static boolean DELETE_ON_LOGOUT = true;
|
||||
@Comment({
|
||||
"If history should be enabled by default for plugins using WorldEdit:",
|
||||
|
@ -0,0 +1,99 @@
|
||||
package com.boydti.fawe.object.collection;
|
||||
|
||||
import java.lang.ref.*;
|
||||
import java.util.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SoftHashMap <K, V> extends AbstractMap<K, V>
|
||||
implements Serializable {
|
||||
/** The internal HashMap that will hold the SoftReference. */
|
||||
private final Map<K, SoftReference<V>> hash =
|
||||
new HashMap<K, SoftReference<V>>();
|
||||
|
||||
private final Map<SoftReference<V>, K> reverseLookup =
|
||||
new HashMap<SoftReference<V>, K>();
|
||||
|
||||
/** Reference queue for cleared SoftReference objects. */
|
||||
private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
|
||||
|
||||
public V get(Object key) {
|
||||
expungeStaleEntries();
|
||||
V result = null;
|
||||
// We get the SoftReference represented by that key
|
||||
SoftReference<V> soft_ref = hash.get(key);
|
||||
if (soft_ref != null) {
|
||||
// From the SoftReference we get the value, which can be
|
||||
// null if it has been garbage collected
|
||||
result = soft_ref.get();
|
||||
if (result == null) {
|
||||
// If the value has been garbage collected, remove the
|
||||
// entry from the HashMap.
|
||||
hash.remove(key);
|
||||
reverseLookup.remove(soft_ref);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void expungeStaleEntries() {
|
||||
Reference<? extends V> sv;
|
||||
while ((sv = queue.poll()) != null) {
|
||||
hash.remove(reverseLookup.remove(sv));
|
||||
}
|
||||
}
|
||||
|
||||
public V put(K key, V value) {
|
||||
expungeStaleEntries();
|
||||
SoftReference<V> soft_ref = new SoftReference<V>(value, queue);
|
||||
reverseLookup.put(soft_ref, key);
|
||||
SoftReference<V> result = hash.put(key, soft_ref);
|
||||
if (result == null) return null;
|
||||
reverseLookup.remove(result);
|
||||
return result.get();
|
||||
}
|
||||
|
||||
public V remove(Object key) {
|
||||
expungeStaleEntries();
|
||||
SoftReference<V> result = hash.remove(key);
|
||||
if (result == null) return null;
|
||||
return result.get();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
hash.clear();
|
||||
reverseLookup.clear();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
expungeStaleEntries();
|
||||
return hash.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the key/values in the map at the point of
|
||||
* calling. However, setValue still sets the value in the
|
||||
* actual SoftHashMap.
|
||||
*/
|
||||
public Set<Entry<K,V>> entrySet() {
|
||||
expungeStaleEntries();
|
||||
Set<Entry<K,V>> result = new LinkedHashSet<Entry<K, V>>();
|
||||
for (final Entry<K, SoftReference<V>> entry : hash.entrySet()) {
|
||||
final V value = entry.getValue().get();
|
||||
if (value != null) {
|
||||
result.add(new Entry<K, V>() {
|
||||
public K getKey() {
|
||||
return entry.getKey();
|
||||
}
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
public V setValue(V v) {
|
||||
entry.setValue(new SoftReference<V>(v, queue));
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.session;
|
||||
|
||||
import com.boydti.fawe.object.collection.SoftHashMap;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
@ -33,6 +34,7 @@ import com.sk89q.worldedit.util.concurrency.EvenMoreExecutors;
|
||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.UUID;
|
||||
@ -60,7 +62,9 @@ public class SessionManager {
|
||||
private static final Logger log = Logger.getLogger(SessionManager.class.getCanonicalName());
|
||||
private final Timer timer = new Timer();
|
||||
private final WorldEdit worldEdit;
|
||||
private final Map<UUID, SessionHolder> sessions = new ConcurrentHashMap<UUID, SessionHolder>(8, 0.9f, 1);
|
||||
private final Map<UUID, SessionHolder> sessions = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||
private final Map<UUID, SessionHolder> softSessions = new SoftHashMap<>();
|
||||
|
||||
private SessionStore store = new VoidStore();
|
||||
private File path;
|
||||
|
||||
@ -90,7 +94,7 @@ public class SessionManager {
|
||||
*/
|
||||
public synchronized boolean contains(SessionOwner owner) {
|
||||
checkNotNull(owner);
|
||||
return sessions.containsKey(getKey(owner));
|
||||
return sessions.containsKey(getKey(owner)) || softSessions.containsKey(owner);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,7 +112,20 @@ public class SessionManager {
|
||||
return holder.session;
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<UUID, SessionHolder>> iter = softSessions.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<UUID, SessionHolder> entry = iter.next();
|
||||
UUID key = entry.getKey();
|
||||
SessionHolder holder = entry.getValue();
|
||||
String test = holder.key.getName();
|
||||
if (test != null && name.equals(test)) {
|
||||
// if (holder.key.isActive()) {
|
||||
iter.remove();
|
||||
sessions.put(key, holder);
|
||||
// }
|
||||
return holder.session;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -122,11 +139,21 @@ public class SessionManager {
|
||||
@Nullable
|
||||
public synchronized LocalSession getIfPresent(SessionOwner owner) {
|
||||
checkNotNull(owner);
|
||||
SessionHolder stored = sessions.get(getKey(owner));
|
||||
UUID key = getKey(owner);
|
||||
SessionHolder stored = sessions.get(key);
|
||||
if (stored != null) {
|
||||
return stored.session;
|
||||
} else {
|
||||
return null;
|
||||
stored = softSessions.get(key);
|
||||
if (stored != null) {
|
||||
// if (stored.key.isActive()) {
|
||||
softSessions.remove(key);
|
||||
sessions.put(key, stored);
|
||||
// }
|
||||
return stored.session;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,10 +183,7 @@ public class SessionManager {
|
||||
session.setConfiguration(config);
|
||||
session.setBlockChangeLimit(config.defaultChangeLimit);
|
||||
|
||||
// Remember the session if the session is still active
|
||||
// if (sessionKey.isActive()) {
|
||||
sessions.put(getKey(owner), new SessionHolder(sessionKey, session));
|
||||
// }
|
||||
sessions.put(getKey(owner), new SessionHolder(sessionKey, session));
|
||||
}
|
||||
|
||||
// Set the limit on the number of blocks that an operation can
|
||||
@ -251,6 +275,14 @@ public class SessionManager {
|
||||
save(sessions.remove(getKey(owner)));
|
||||
}
|
||||
|
||||
public synchronized void forget(SessionOwner owner) {
|
||||
checkNotNull(owner);
|
||||
UUID key = getKey(owner);
|
||||
SessionHolder holder = sessions.remove(key);
|
||||
softSessions.put(key, holder);
|
||||
save(holder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all sessions.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user