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; package com.massivecraft.factions;
import org.bukkit.ChatColor;
import com.massivecraft.factions.adapter.BoardAdapter; import com.massivecraft.factions.adapter.BoardAdapter;
import com.massivecraft.factions.adapter.BoardMapAdapter; import com.massivecraft.factions.adapter.BoardMapAdapter;
import com.massivecraft.factions.adapter.FactionPreprocessAdapter; 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_SAFEZONE = "safezone";
public final static String ID_WARZONE = "warzone"; 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 // INSTANCE & CONSTRUCT
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -43,7 +43,11 @@ public class FactionPreprocessAdapter implements JsonDeserializer<Faction>
rename(jsonObject, "permOverrides", "perms"); 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); JsonElement element = jsonObject.remove(from);
if (element != null) jsonObject.add(to, element); if (element != null) jsonObject.add(to, element);

View File

@ -51,7 +51,7 @@ public class CmdFactionsPerm extends FactionsCommand
msg(MPerm.getStateHeaders()); msg(MPerm.getStateHeaders());
for (MPerm perm : MPerm.getAll()) for (MPerm perm : MPerm.getAll())
{ {
msg(perm.getStateInfo(faction.getPermittedRelations(perm), true)); msg(perm.getStateInfo(faction.getPermitted(perm), true));
} }
return; return;
} }
@ -65,7 +65,7 @@ public class CmdFactionsPerm extends FactionsCommand
{ {
msg(Txt.titleize("Perm for " + faction.describeTo(msender, true))); msg(Txt.titleize("Perm for " + faction.describeTo(msender, true)));
msg(MPerm.getStateHeaders()); msg(MPerm.getStateHeaders());
msg(mperm.getStateInfo(faction.getPermittedRelations(mperm), true)); msg(mperm.getStateInfo(faction.getPermitted(mperm), true));
return; return;
} }
@ -105,7 +105,7 @@ public class CmdFactionsPerm extends FactionsCommand
// Inform // Inform
msg(Txt.titleize("Perm for " + faction.describeTo(msender, true))); msg(Txt.titleize("Perm for " + faction.describeTo(msender, true)));
msg(MPerm.getStateHeaders()); 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.Rel;
import com.massivecraft.factions.RelationParticipator; import com.massivecraft.factions.RelationParticipator;
import com.massivecraft.factions.util.*; 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.mixin.Mixin;
import com.massivecraft.massivecore.money.Money; import com.massivecraft.massivecore.money.Money;
import com.massivecraft.massivecore.ps.PS; 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. // This is the ids of the invited players.
// They are actually "senderIds" since you can invite "@console" to your faction. // They are actually "senderIds" since you can invite "@console" to your faction.
// Null means no one is invited // 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. // The keys in this map are factionIds.
// Null means no special relation whishes. // 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. // The flag overrides are modifications to the default values.
// Null means default. // 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. // The perm overrides are modifications to the default values.
// Null means default. // Null means default.
private Map<String, Set<Rel>> perms = null; private MassiveMapDef<String, Set<Rel>> perms = new MassiveMapDef<String, Set<Rel>>();
// -------------------------------------------- // // -------------------------------------------- //
// FIELD: id // FIELD: id
@ -391,33 +394,27 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
// FIELD: open // FIELD: open
// -------------------------------------------- // // -------------------------------------------- //
/* // Nowadays this is a flag!
@Deprecated
public boolean isDefaultOpen() public boolean isDefaultOpen()
{ {
return MConf.get().defaultFactionOpen; return MFlag.getFlagOpen().isStandard();
} }
@Deprecated
public boolean isOpen() public boolean isOpen()
{ {
Boolean ret = this.open; return this.getFlag(MFlag.getFlagOpen());
if (ret == null) ret = this.isDefaultOpen();
return ret;
} }
@Deprecated
public void setOpen(Boolean open) public void setOpen(Boolean open)
{ {
// Clean input MFlag flag = MFlag.getFlagOpen();
Boolean target = open; if (open == null) open = flag.isStandard();
this.setFlag(flag, open);
// Detect Nochange }
if (MUtil.equals(this.open, target)) return;
// Apply
this.open = target;
// Mark as changed
this.changed();
}*/
// -------------------------------------------- // // -------------------------------------------- //
// FIELD: invitedPlayerIds // FIELD: invitedPlayerIds
@ -427,22 +424,15 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
public TreeSet<String> getInvitedPlayerIds() public TreeSet<String> getInvitedPlayerIds()
{ {
TreeSet<String> ret = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); return this.invitedPlayerIds;
if (this.invitedPlayerIds != null) ret.addAll(this.invitedPlayerIds);
return ret;
} }
public void setInvitedPlayerIds(Collection<String> invitedPlayerIds) public void setInvitedPlayerIds(Collection<String> invitedPlayerIds)
{ {
// Clean input // Clean input
TreeSet<String> target; MassiveTreeSetDef<String, CaseInsensitiveComparator> target = new MassiveTreeSetDef<String, CaseInsensitiveComparator>(CaseInsensitiveComparator.get());
if (invitedPlayerIds == null || invitedPlayerIds.isEmpty()) if (invitedPlayerIds != null)
{ {
target = null;
}
else
{
target = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (String invitedPlayerId : invitedPlayerIds) for (String invitedPlayerId : invitedPlayerIds)
{ {
target.add(invitedPlayerId.toLowerCase()); target.add(invitedPlayerId.toLowerCase());
@ -501,23 +491,13 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
public Map<String, Rel> getRelationWishes() public Map<String, Rel> getRelationWishes()
{ {
Map<String, Rel> ret = new LinkedHashMap<String, Rel>(); return this.relationWishes;
if (this.relationWishes != null) ret.putAll(this.relationWishes);
return ret;
} }
public void setRelationWishes(Map<String, Rel> relationWishes) public void setRelationWishes(Map<String, Rel> relationWishes)
{ {
// Clean input // Clean input
Map<String, Rel> target; MassiveMapDef<String, Rel> target = new MassiveMapDef<String, Rel>(relationWishes);
if (relationWishes == null || relationWishes.isEmpty())
{
target = null;
}
else
{
target = new LinkedHashMap<String, Rel>(relationWishes);
}
// Detect Nochange // Detect Nochange
if (MUtil.equals(this.relationWishes, target)) return; if (MUtil.equals(this.relationWishes, target)) return;
@ -604,81 +584,31 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
} }
// ... and if anything is explicitly set we use that info ... // ... 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())
{ {
Iterator<Entry<String, Boolean>> iter = this.flags.entrySet().iterator(); // ... for each entry ...
while (iter.hasNext()) Entry<String, Boolean> entry = iter.next();
// ... extract id and remove null values ...
String id = entry.getKey();
if (id == null)
{ {
// ... for each entry ... iter.remove();
Entry<String, Boolean> entry = iter.next(); this.changed();
continue;
// ... extract id and remove null values ...
String id = entry.getKey();
if (id == null)
{
iter.remove();
continue;
}
// ... resolve object and skip unknowns ...
MFlag mflag = MFlag.get(id);
if (mflag == null) continue;
ret.put(mflag, entry.getValue());
} }
// ... resolve object and skip unknowns ...
MFlag mflag = MFlag.get(id);
if (mflag == null) continue;
ret.put(mflag, entry.getValue());
} }
return ret; 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) public void setFlags(Map<MFlag, Boolean> flags)
{ {
Map<String, Boolean> flagIds = new LinkedHashMap<String, Boolean>(); Map<String, Boolean> flagIds = new LinkedHashMap<String, Boolean>();
@ -689,17 +619,79 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
setFlagIds(flagIds); 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 // 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) 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(); if (flagId == null) throw new NullPointerException("flagId");
flags.put(flag, value);
this.setFlags(flags); 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,85 +710,30 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
} }
// ... and if anything is explicitly set we use that info ... // ... 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())
{ {
Iterator<Entry<String, Set<Rel>>> iter = this.perms.entrySet().iterator(); // ... for each entry ...
while (iter.hasNext()) Entry<String, Set<Rel>> entry = iter.next();
// ... extract id and remove null values ...
String id = entry.getKey();
if (id == null)
{ {
// ... for each entry ... iter.remove();
Entry<String, Set<Rel>> entry = iter.next(); continue;
// ... extract id and remove null values ...
String id = entry.getKey();
if (id == null)
{
iter.remove();
continue;
}
// ... resolve object and skip unknowns ...
MPerm mperm = MPerm.get(id);
if (mperm == null) continue;
ret.put(mperm, new LinkedHashSet<Rel>(entry.getValue()));
} }
// ... resolve object and skip unknowns ...
MPerm mperm = MPerm.get(id);
if (mperm == null) continue;
ret.put(mperm, new LinkedHashSet<Rel>(entry.getValue()));
} }
return ret; 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) public void setPerms(Map<MPerm, Set<Rel>> perms)
{ {
Map<String, Set<Rel>> permIds = new LinkedHashMap<String, Set<Rel>>(); Map<String, Set<Rel>> permIds = new LinkedHashMap<String, Set<Rel>>();
@ -807,13 +744,98 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
setPermIds(permIds); 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 // 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) public Set<Rel> getPermittedRelations(MPerm perm)
{ {
return this.getPerms().get(perm); return this.getPerms().get(perm);
} }
// ---
// TODO: Fix these below. They are reworking the whole map.
public void setPermittedRelations(MPerm perm, Set<Rel> rels) public void setPermittedRelations(MPerm perm, Set<Rel> rels)
{ {
Map<MPerm, Set<Rel>> perms = this.getPerms(); Map<MPerm, Set<Rel>> perms = this.getPerms();

View File

@ -2,8 +2,6 @@ package com.massivecraft.factions.entity;
import java.util.*; import java.util.*;
import org.bukkit.ChatColor;
import com.massivecraft.massivecore.store.Coll; import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.MStore; import com.massivecraft.massivecore.store.MStore;
import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.util.Txt;
@ -89,7 +87,7 @@ public class FactionColl extends Coll<Faction>
faction = this.create(id); faction = this.create(id);
faction.setName(ChatColor.DARK_GREEN+"Wilderness"); faction.setName(Factions.NAME_NONE_DEFAULT);
faction.setDescription(null); faction.setDescription(null);
faction.setFlag(MFlag.getFlagOpen(), false); faction.setFlag(MFlag.getFlagOpen(), false);
@ -123,7 +121,7 @@ public class FactionColl extends Coll<Faction>
faction = this.create(id); faction = this.create(id);
faction.setName("SafeZone"); faction.setName(Factions.NAME_SAFEZONE_DEFAULT);
faction.setDescription("Free from PVP and monsters"); faction.setDescription("Free from PVP and monsters");
faction.setFlag(MFlag.getFlagOpen(), false); faction.setFlag(MFlag.getFlagOpen(), false);
@ -156,7 +154,7 @@ public class FactionColl extends Coll<Faction>
faction = this.create(id); faction = this.create(id);
faction.setName("WarZone"); faction.setName(Factions.NAME_WARZONE_DEFAULT);
faction.setDescription("Not the safest place to be"); faction.setDescription("Not the safest place to be");
faction.setFlag(MFlag.getFlagOpen(), false); 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"); if (hostFaction == null) throw new NullPointerException("hostFaction");
Rel rel = faction.getRelationTo(hostFaction); Rel rel = faction.getRelationTo(hostFaction);
return hostFaction.isPermitted(this, rel);
Set<Rel> permittedRelations = hostFaction.getPermittedRelations(this);
return permittedRelations.contains(rel);
} }
public boolean has(MPlayer mplayer, Faction hostFaction, boolean verboose) 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; if (mplayer.isUsingAdminMode()) return true;
Rel rel = mplayer.getRelationTo(hostFaction); Rel rel = mplayer.getRelationTo(hostFaction);
Set<Rel> permittedRelations = hostFaction.getPermittedRelations(this); if (hostFaction.isPermitted(this, rel)) return true;
if (permittedRelations.contains(rel)) return true;
if (verboose) mplayer.sendMessage(this.createDeniedMessage(mplayer, hostFaction)); if (verboose) mplayer.sendMessage(this.createDeniedMessage(mplayer, hostFaction));