Use Massive collections to avoid null checks, convert to lower case and use quicker permission and flag checking.

This commit is contained in:
Olof Larsson 2014-11-13 11:41:21 +01:00
parent aa0edb28b7
commit a376fffa47
6 changed files with 227 additions and 200 deletions

View File

@ -1,5 +1,7 @@
package com.massivecraft.factions;
import org.bukkit.ChatColor;
import com.massivecraft.factions.adapter.BoardAdapter;
import com.massivecraft.factions.adapter.BoardMapAdapter;
import com.massivecraft.factions.adapter.FactionPreprocessAdapter;
@ -61,6 +63,10 @@ public class Factions extends MassivePlugin
public final static String ID_SAFEZONE = "safezone";
public final static String ID_WARZONE = "warzone";
public final static String NAME_NONE_DEFAULT = ChatColor.DARK_GREEN.toString() + "Wilderness";
public final static String NAME_SAFEZONE_DEFAULT = "SafeZone";
public final static String NAME_WARZONE_DEFAULT = "WarZone";
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //

View File

@ -43,7 +43,11 @@ public class FactionPreprocessAdapter implements JsonDeserializer<Faction>
rename(jsonObject, "permOverrides", "perms");
}
public void rename(final JsonObject jsonObject, final String from, final String to)
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static void rename(final JsonObject jsonObject, final String from, final String to)
{
JsonElement element = jsonObject.remove(from);
if (element != null) jsonObject.add(to, element);

View File

@ -51,7 +51,7 @@ public class CmdFactionsPerm extends FactionsCommand
msg(MPerm.getStateHeaders());
for (MPerm perm : MPerm.getAll())
{
msg(perm.getStateInfo(faction.getPermittedRelations(perm), true));
msg(perm.getStateInfo(faction.getPermitted(perm), true));
}
return;
}
@ -65,7 +65,7 @@ public class CmdFactionsPerm extends FactionsCommand
{
msg(Txt.titleize("Perm for " + faction.describeTo(msender, true)));
msg(MPerm.getStateHeaders());
msg(mperm.getStateInfo(faction.getPermittedRelations(mperm), true));
msg(mperm.getStateInfo(faction.getPermitted(mperm), true));
return;
}
@ -105,7 +105,7 @@ public class CmdFactionsPerm extends FactionsCommand
// Inform
msg(Txt.titleize("Perm for " + faction.describeTo(msender, true)));
msg(MPerm.getStateHeaders());
msg(mperm.getStateInfo(faction.getPermittedRelations(mperm), true));
msg(mperm.getStateInfo(faction.getPermitted(mperm), true));
}
}

View File

@ -15,6 +15,9 @@ import com.massivecraft.factions.Lang;
import com.massivecraft.factions.Rel;
import com.massivecraft.factions.RelationParticipator;
import com.massivecraft.factions.util.*;
import com.massivecraft.massivecore.CaseInsensitiveComparator;
import com.massivecraft.massivecore.collections.MassiveMapDef;
import com.massivecraft.massivecore.collections.MassiveTreeSetDef;
import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.money.Money;
import com.massivecraft.massivecore.ps.PS;
@ -116,19 +119,19 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
// This is the ids of the invited players.
// They are actually "senderIds" since you can invite "@console" to your faction.
// Null means no one is invited
private Set<String> invitedPlayerIds = null;
private MassiveTreeSetDef<String, CaseInsensitiveComparator> invitedPlayerIds = new MassiveTreeSetDef<String, CaseInsensitiveComparator>(CaseInsensitiveComparator.get());
// The keys in this map are factionIds.
// Null means no special relation whishes.
private Map<String, Rel> relationWishes = null;
private MassiveMapDef<String, Rel> relationWishes = new MassiveMapDef<String, Rel>();
// The flag overrides are modifications to the default values.
// Null means default.
private Map<String, Boolean> flags = null;
private MassiveMapDef<String, Boolean> flags = new MassiveMapDef<String, Boolean>();
// The perm overrides are modifications to the default values.
// Null means default.
private Map<String, Set<Rel>> perms = null;
private MassiveMapDef<String, Set<Rel>> perms = new MassiveMapDef<String, Set<Rel>>();
// -------------------------------------------- //
// FIELD: id
@ -391,33 +394,27 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
// FIELD: open
// -------------------------------------------- //
/*
// Nowadays this is a flag!
@Deprecated
public boolean isDefaultOpen()
{
return MConf.get().defaultFactionOpen;
return MFlag.getFlagOpen().isStandard();
}
@Deprecated
public boolean isOpen()
{
Boolean ret = this.open;
if (ret == null) ret = this.isDefaultOpen();
return ret;
return this.getFlag(MFlag.getFlagOpen());
}
@Deprecated
public void setOpen(Boolean open)
{
// Clean input
Boolean target = open;
// Detect Nochange
if (MUtil.equals(this.open, target)) return;
// Apply
this.open = target;
// Mark as changed
this.changed();
}*/
MFlag flag = MFlag.getFlagOpen();
if (open == null) open = flag.isStandard();
this.setFlag(flag, open);
}
// -------------------------------------------- //
// FIELD: invitedPlayerIds
@ -427,22 +424,15 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
public TreeSet<String> getInvitedPlayerIds()
{
TreeSet<String> ret = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
if (this.invitedPlayerIds != null) ret.addAll(this.invitedPlayerIds);
return ret;
return this.invitedPlayerIds;
}
public void setInvitedPlayerIds(Collection<String> invitedPlayerIds)
{
// Clean input
TreeSet<String> target;
if (invitedPlayerIds == null || invitedPlayerIds.isEmpty())
MassiveTreeSetDef<String, CaseInsensitiveComparator> target = new MassiveTreeSetDef<String, CaseInsensitiveComparator>(CaseInsensitiveComparator.get());
if (invitedPlayerIds != null)
{
target = null;
}
else
{
target = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (String invitedPlayerId : invitedPlayerIds)
{
target.add(invitedPlayerId.toLowerCase());
@ -501,23 +491,13 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
public Map<String, Rel> getRelationWishes()
{
Map<String, Rel> ret = new LinkedHashMap<String, Rel>();
if (this.relationWishes != null) ret.putAll(this.relationWishes);
return ret;
return this.relationWishes;
}
public void setRelationWishes(Map<String, Rel> relationWishes)
{
// Clean input
Map<String, Rel> target;
if (relationWishes == null || relationWishes.isEmpty())
{
target = null;
}
else
{
target = new LinkedHashMap<String, Rel>(relationWishes);
}
MassiveMapDef<String, Rel> target = new MassiveMapDef<String, Rel>(relationWishes);
// Detect Nochange
if (MUtil.equals(this.relationWishes, target)) return;
@ -604,8 +584,6 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
}
// ... and if anything is explicitly set we use that info ...
if (this.flags != null)
{
Iterator<Entry<String, Boolean>> iter = this.flags.entrySet().iterator();
while (iter.hasNext())
{
@ -617,6 +595,7 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
if (id == null)
{
iter.remove();
this.changed();
continue;
}
@ -626,59 +605,10 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
ret.put(mflag, entry.getValue());
}
}
return ret;
}
public void setFlagIds(Map<String, Boolean> flags)
{
// Clean input
Map<String, Boolean> target = null;
if (flags != null)
{
// We start out with what was suggested
target = new LinkedHashMap<String, Boolean>(flags);
// However if the context is fully live we try to throw some default values away.
if (this.attached() && Factions.get().isDatabaseInitialized())
{
Iterator<Entry<String, Boolean>> iter = target.entrySet().iterator();
while (iter.hasNext())
{
// For each entry ...
Entry<String, Boolean> entry = iter.next();
// ... extract id and remove null values ...
String id = entry.getKey();
if (id == null)
{
iter.remove();
continue;
}
// ... remove if known and standard ...
MFlag mflag = MFlag.get(id);
if (mflag != null && mflag.isStandard() == entry.getValue())
{
iter.remove();
}
}
if (target.isEmpty()) target = null;
}
}
// Detect Nochange
if (MUtil.equals(this.flags, target)) return;
// Apply
this.flags = target;
// Mark as changed
this.changed();
}
public void setFlags(Map<MFlag, Boolean> flags)
{
Map<String, Boolean> flagIds = new LinkedHashMap<String, Boolean>();
@ -689,17 +619,79 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
setFlagIds(flagIds);
}
public void setFlagIds(Map<String, Boolean> flagIds)
{
// Clean input
MassiveMapDef<String, Boolean> target = new MassiveMapDef<String, Boolean>();
for (Entry<String, Boolean> entry : flagIds.entrySet())
{
String key = entry.getKey();
if (key == null) continue;
key = key.toLowerCase(); // Lowercased Keys Version 2.6.0 --> 2.7.0
Boolean value = entry.getValue();
if (value == null) continue;
target.put(key, value);
}
// Detect Nochange
if (MUtil.equals(this.flags, target)) return;
// Apply
this.flags = new MassiveMapDef<String, Boolean>(target);
// Mark as changed
this.changed();
}
// FINER
public boolean getFlag(String flagId)
{
if (flagId == null) throw new NullPointerException("flagId");
Boolean ret = this.flags.get(flagId);
if (ret != null) return ret;
MFlag flag = MFlag.get(flagId);
if (flag == null) throw new NullPointerException("flag");
return flag.isStandard();
}
public boolean getFlag(MFlag flag)
{
return this.getFlags().get(flag);
if (flag == null) throw new NullPointerException("flag");
String flagId = flag.getId();
if (flagId == null) throw new NullPointerException("flagId");
Boolean ret = this.flags.get(flagId);
if (ret != null) return ret;
return flag.isStandard();
}
public void setFlag(MFlag flag, boolean value)
public Boolean setFlag(String flagId, boolean value)
{
Map<MFlag, Boolean> flags = this.getFlags();
flags.put(flag, value);
this.setFlags(flags);
if (flagId == null) throw new NullPointerException("flagId");
Boolean ret = this.flags.put(flagId, value);
if (ret == null || ret != value) this.changed();
return ret;
}
public Boolean setFlag(MFlag flag, boolean value)
{
if (flag == null) throw new NullPointerException("flag");
String flagId = flag.getId();
if (flagId == null) throw new NullPointerException("flagId");
Boolean ret = this.flags.put(flagId, value);
if (ret == null || ret != value) this.changed();
return ret;
}
// -------------------------------------------- //
@ -718,8 +710,6 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
}
// ... and if anything is explicitly set we use that info ...
if (this.perms != null)
{
Iterator<Entry<String, Set<Rel>>> iter = this.perms.entrySet().iterator();
while (iter.hasNext())
{
@ -740,63 +730,10 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
ret.put(mperm, new LinkedHashSet<Rel>(entry.getValue()));
}
}
return ret;
}
public void setPermIds(Map<String, Set<Rel>> perms)
{
// Clean input
Map<String, Set<Rel>> target = null;
if (perms != null)
{
// We start out with what was suggested
target = new LinkedHashMap<String, Set<Rel>>();
for (Entry<String, Set<Rel>> entry : perms.entrySet())
{
target.put(entry.getKey(), new LinkedHashSet<Rel>(entry.getValue()));
}
// However if the context is fully live we try to throw some default values away.
if (this.attached() && Factions.get().isDatabaseInitialized())
{
Iterator<Entry<String, Set<Rel>>> iter = target.entrySet().iterator();
while (iter.hasNext())
{
// For each entry ...
Entry<String, Set<Rel>> entry = iter.next();
// ... extract id and remove null values ...
String id = entry.getKey();
if (id == null)
{
iter.remove();
continue;
}
// ... remove if known and standard ...
MPerm mperm = MPerm.get(id);
if (mperm != null && mperm.getStandard().equals(entry.getValue()))
{
iter.remove();
}
}
if (target.isEmpty()) target = null;
}
}
// Detect Nochange
if (MUtil.equals(this.perms, target)) return;
// Apply
this.perms = target;
// Mark as changed
this.changed();
}
public void setPerms(Map<MPerm, Set<Rel>> perms)
{
Map<String, Set<Rel>> permIds = new LinkedHashMap<String, Set<Rel>>();
@ -807,13 +744,98 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
setPermIds(permIds);
}
public void setPermIds(Map<String, Set<Rel>> perms)
{
// Clean input
MassiveMapDef<String, Set<Rel>> target = new MassiveMapDef<String, Set<Rel>>();
for (Entry<String, Set<Rel>> entry : perms.entrySet())
{
String key = entry.getKey();
if (key == null) continue;
key = key.toLowerCase(); // Lowercased Keys Version 2.6.0 --> 2.7.0
Set<Rel> value = entry.getValue();
if (value == null) continue;
target.put(key, value);
}
// Detect Nochange
if (MUtil.equals(this.perms, target)) return;
// Apply
this.perms = target;
// Mark as changed
this.changed();
}
// FINER
public boolean isPermitted(String permId, Rel rel)
{
if (permId == null) throw new NullPointerException("permId");
Set<Rel> rels = this.perms.get(permId);
if (rels != null) return rels.contains(rel);
MPerm perm = MPerm.get(permId);
if (perm == null) throw new NullPointerException("perm");
return perm.getStandard().contains(rel);
}
public boolean isPermitted(MPerm perm, Rel rel)
{
if (perm == null) throw new NullPointerException("perm");
String permId = perm.getId();
if (permId == null) throw new NullPointerException("permId");
Set<Rel> rels = this.perms.get(permId);
if (rels != null) return rels.contains(rel);
return perm.getStandard().contains(rel);
}
// ---
public Set<Rel> getPermitted(MPerm perm)
{
if (perm == null) throw new NullPointerException("perm");
String permId = perm.getId();
if (permId == null) throw new NullPointerException("permId");
Set<Rel> rels = this.perms.get(permId);
if (rels != null) return rels;
return perm.getStandard();
}
public Set<Rel> getPermitted(String permId)
{
if (permId == null) throw new NullPointerException("permId");
Set<Rel> rels = this.perms.get(permId);
if (rels != null) return rels;
MPerm perm = MPerm.get(permId);
if (perm == null) throw new NullPointerException("perm");
return perm.getStandard();
}
@Deprecated
// Use getPermitted instead. It's much quicker although not immutable.
public Set<Rel> getPermittedRelations(MPerm perm)
{
return this.getPerms().get(perm);
}
// ---
// TODO: Fix these below. They are reworking the whole map.
public void setPermittedRelations(MPerm perm, Set<Rel> rels)
{
Map<MPerm, Set<Rel>> perms = this.getPerms();

View File

@ -2,8 +2,6 @@ package com.massivecraft.factions.entity;
import java.util.*;
import org.bukkit.ChatColor;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.MStore;
import com.massivecraft.massivecore.util.Txt;
@ -89,7 +87,7 @@ public class FactionColl extends Coll<Faction>
faction = this.create(id);
faction.setName(ChatColor.DARK_GREEN+"Wilderness");
faction.setName(Factions.NAME_NONE_DEFAULT);
faction.setDescription(null);
faction.setFlag(MFlag.getFlagOpen(), false);
@ -123,7 +121,7 @@ public class FactionColl extends Coll<Faction>
faction = this.create(id);
faction.setName("SafeZone");
faction.setName(Factions.NAME_SAFEZONE_DEFAULT);
faction.setDescription("Free from PVP and monsters");
faction.setFlag(MFlag.getFlagOpen(), false);
@ -156,7 +154,7 @@ public class FactionColl extends Coll<Faction>
faction = this.create(id);
faction.setName("WarZone");
faction.setName(Factions.NAME_WARZONE_DEFAULT);
faction.setDescription("Not the safest place to be");
faction.setFlag(MFlag.getFlagOpen(), false);

View File

@ -277,9 +277,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable
if (hostFaction == null) throw new NullPointerException("hostFaction");
Rel rel = faction.getRelationTo(hostFaction);
Set<Rel> permittedRelations = hostFaction.getPermittedRelations(this);
return permittedRelations.contains(rel);
return hostFaction.isPermitted(this, rel);
}
public boolean has(MPlayer mplayer, Faction hostFaction, boolean verboose)
@ -291,8 +289,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable
if (mplayer.isUsingAdminMode()) return true;
Rel rel = mplayer.getRelationTo(hostFaction);
Set<Rel> permittedRelations = hostFaction.getPermittedRelations(this);
if (permittedRelations.contains(rel)) return true;
if (hostFaction.isPermitted(this, rel)) return true;
if (verboose) mplayer.sendMessage(this.createDeniedMessage(mplayer, hostFaction));