Improve getInstances efficiency

This commit is contained in:
Nathan Braun 2015-08-20 12:32:22 -07:00
parent 486df1b504
commit d14d9aec50

View file

@ -29,6 +29,7 @@ public abstract class CoreAbility implements Ability {
private static ConcurrentHashMap<Integer, CoreAbility> instances = new ConcurrentHashMap<>(); private static ConcurrentHashMap<Integer, CoreAbility> instances = new ConcurrentHashMap<>();
//protected static AbilityMap<Ability> instances = new AbilityMap<>(); //protected static AbilityMap<Ability> instances = new AbilityMap<>();
private static ConcurrentHashMap<StockAbility, ArrayList<Integer>> abilityMap = new ConcurrentHashMap<>(); private static ConcurrentHashMap<StockAbility, ArrayList<Integer>> abilityMap = new ConcurrentHashMap<>();
private static ConcurrentHashMap<Class<? extends CoreAbility>, ConcurrentHashMap<Integer, CoreAbility>> classAbilityMap = new ConcurrentHashMap<>();
private static int ID = Integer.MIN_VALUE; private static int ID = Integer.MIN_VALUE;
private final StockAbility stockAbility = getStockAbility(); private final StockAbility stockAbility = getStockAbility();
@ -49,14 +50,11 @@ public abstract class CoreAbility implements Ability {
return true; return true;
} }
/* /*
List<CoreAbility> abilities = getAbilitiesFromPlayer(player); * List<CoreAbility> abilities = getAbilitiesFromPlayer(player); for
for (CoreAbility coreAbility : abilities) { * (CoreAbility coreAbility : abilities) { if
if (ability.isInstance(coreAbility)) { * (ability.isInstance(coreAbility)) { if
if (coreAbility.getPlayer().getUniqueId().equals(player.getUniqueId())) { * (coreAbility.getPlayer().getUniqueId().equals(player.getUniqueId()))
return true; * { return true; } } }
}
}
}
*/ */
return false; return false;
} }
@ -108,8 +106,8 @@ public abstract class CoreAbility implements Ability {
/** /**
* An access method to get an the instances of a {@link StockAbility}. * An access method to get an the instances of a {@link StockAbility}.
* <b>IMPORTANT: </b> If this is used in a for each loop use * <b>IMPORTANT: </b> If this is used in a for each loop use
* {@link #getAbility(int)} to get the ability. Incorrect usage may * {@link #getAbility(int)} to get the ability. Incorrect usage may cause
* cause over looping and is capable of hanging the thead. * over looping and is capable of hanging the thead.
* *
* @param ability The instances map to get * @param ability The instances map to get
* @return a map of instances from the specified {@link StockAbility} * @return a map of instances from the specified {@link StockAbility}
@ -128,21 +126,16 @@ public abstract class CoreAbility implements Ability {
/** /**
* An access method to get an the instances of a {@link CoreAbility} by its * An access method to get an the instances of a {@link CoreAbility} by its
* class. <b>IMPORTANT: </b> If this is used in a for each loop use * class. <b>IMPORTANT: </b> If this is used in a for each loop use
* {@link #getAbility(int)} to get the ability. Incorrect usage may * {@link #getAbility(int)} to get the ability. Incorrect usage may cause
* cause over looping and is capable of hanging the thead. * over looping and is capable of hanging the thead.
* *
* @param ability The instances map to get * @param ability The instances map to get
* @return a map of instances from the specified class * @return a map of instances from the specified class
* @see #getInstances(StockAbility) * @see #getInstances(StockAbility)
*/ */
public final static ConcurrentHashMap<Integer, CoreAbility> getInstances(Class<? extends CoreAbility> ability) { public final static ConcurrentHashMap<Integer, CoreAbility> getInstances(Class<? extends CoreAbility> ability) {
ConcurrentHashMap<Integer, CoreAbility> instanceMap = new ConcurrentHashMap<>(); ConcurrentHashMap<Integer, CoreAbility> instanceMap = classAbilityMap.get(ability.getClass());
for (Integer id : instances.keySet()) { return instanceMap != null ? instanceMap : new ConcurrentHashMap<Integer, CoreAbility>();
if (ability.isInstance(instances.get(id))) {
instanceMap.put(id, instances.get(id));
}
}
return instanceMap;
} }
//TODO: Update bending managers to use bellow method //TODO: Update bending managers to use bellow method
@ -298,7 +291,14 @@ public abstract class CoreAbility implements Ability {
this.id = ID; this.id = ID;
this.uniqueId = player.getUniqueId(); this.uniqueId = player.getUniqueId();
this.player = player; this.player = player;
Class<? extends CoreAbility> classKey = ability.getClass();
if (!classAbilityMap.containsKey(classKey)) {
classAbilityMap.put(classKey, new ConcurrentHashMap<Integer, CoreAbility>());
}
classAbilityMap.get(classKey).put(id, ability);
instances.put(id, ability); instances.put(id, ability);
if (stockAbility != null) { if (stockAbility != null) {
if (abilityMap.containsKey(stockAbility)) { if (abilityMap.containsKey(stockAbility)) {
abilityMap.get(stockAbility).add(id); abilityMap.get(stockAbility).add(id);
@ -306,6 +306,7 @@ public abstract class CoreAbility implements Ability {
abilityMap.put(stockAbility, new ArrayList<Integer>(Arrays.asList(id))); abilityMap.put(stockAbility, new ArrayList<Integer>(Arrays.asList(id)));
} }
} }
if (ID == Integer.MAX_VALUE) if (ID == Integer.MAX_VALUE)
ID = Integer.MIN_VALUE; ID = Integer.MIN_VALUE;
ID++; ID++;
@ -329,6 +330,11 @@ public abstract class CoreAbility implements Ability {
if (instances.containsKey(id)) { if (instances.containsKey(id)) {
instances.remove(id); instances.remove(id);
} }
if (classAbilityMap.containsKey(this.getClass())) {
classAbilityMap.get(this.getClass()).remove(id);
}
if (stockAbility != null) { if (stockAbility != null) {
if (abilityMap.containsKey(stockAbility)) { if (abilityMap.containsKey(stockAbility)) {
abilityMap.get(stockAbility).remove(id); abilityMap.get(stockAbility).remove(id);