Implement locks to hopefully resolve race conditions with I/O - experimental

This commit is contained in:
Luck
2016-10-01 19:03:05 +01:00
Unverified
parent b5ece8b5bd
commit 4787361e66
22 changed files with 1156 additions and 875 deletions
@@ -26,18 +26,32 @@ import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* An abstract manager class
* @param <I> the class used to identify each object held in this manager
* @param <T> the class this manager is "managing"
*/
public abstract class AbstractManager<I, T extends Identifiable<I>> {
public abstract class AbstractManager<I, T extends Identifiable<I>> implements Function<I, T> {
private final Map<I, T> objects = new HashMap<>();
public final Map<I, T> getAll() {
Map<I, T> map;
synchronized (objects) {
return ImmutableMap.copyOf(objects);
map = ImmutableMap.copyOf(objects);
}
return map;
}
/**
* Get an object by id
* @param id The id to search by
* @return a {@link T} object if the object is loaded or makes and returns a new object
*/
public final T getOrMake(I id) {
synchronized (objects) {
return objects.computeIfAbsent(id, this);
}
}
@@ -52,38 +66,6 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> {
}
}
/**
* Add a object to the loaded objects map
* @param t The object to add
*/
public final void set(T t) {
preSet(t);
synchronized (objects) {
objects.put(t.getId(), t);
}
}
protected void preSet(T t) {
}
/**
* Updates (or sets if the object wasn't already loaded) an object in the objects map
* @param t The object to update or set
*/
public final void updateOrSet(T t) {
synchronized (objects) {
if (!isLoaded(t.getId())) {
// The object isn't already loaded
set(t);
} else {
copy(t, objects.get(t.getId()));
}
}
}
public abstract void copy(T from, T to);
/**
* Check to see if a object is loaded or not
* @param id The id of the object
@@ -101,9 +83,11 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> {
*/
public final void unload(T t) {
if (t != null) {
preUnload(t);
synchronized (objects) {
objects.remove(t.getId());
objects.computeIfPresent(t.getId(), (i, t1) -> {
preUnload(t1);
return null;
});
}
}
}
@@ -117,15 +101,9 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> {
*/
public final void unloadAll() {
synchronized (objects) {
objects.values().forEach(this::preUnload);
objects.clear();
}
}
/**
* Makes a new object
* @param id the id of the object
* @return a new {@link T} object
*/
public abstract T make(I id);
}