diff --git a/src/com/massivecraft/massivecore/cmd/massivecore/CmdMassiveCoreStoreStats.java b/src/com/massivecraft/massivecore/cmd/massivecore/CmdMassiveCoreStoreStats.java index 94de6fd0..034667b3 100644 --- a/src/com/massivecraft/massivecore/cmd/massivecore/CmdMassiveCoreStoreStats.java +++ b/src/com/massivecraft/massivecore/cmd/massivecore/CmdMassiveCoreStoreStats.java @@ -57,8 +57,8 @@ public class CmdMassiveCoreStoreStats extends MassiveCommand { String name = entry.getKey(); Coll coll = entry.getValue(); - long in = coll.getSyncCount(Coll.TOTAL, true); - long out = coll.getSyncCount(Coll.TOTAL, false); + long in = coll.getSyncCountFixed(Coll.TOTAL, true); + long out = coll.getSyncCountFixed(Coll.TOTAL, false); msg("%s | %d | %d", name, in, out); } diff --git a/src/com/massivecraft/massivecore/store/Coll.java b/src/com/massivecraft/massivecore/store/Coll.java index bed79b3b..4f615b04 100644 --- a/src/com/massivecraft/massivecore/store/Coll.java +++ b/src/com/massivecraft/massivecore/store/Coll.java @@ -25,7 +25,7 @@ import com.massivecraft.massivecore.xlib.gson.Gson; import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject; -public class Coll implements CollInterface +public class Coll extends CollAbstract { // -------------------------------------------- // // GLOBAL REGISTRY @@ -104,19 +104,13 @@ public class Coll implements CollInterface protected Map entity2id; @Override public Map getId2entity() { return Collections.unmodifiableMap(this.id2entity); } - @Override - public E get(Object oid) - { - return this.get(oid, this.isCreative()); - } @Override - public E get(Object oid, boolean creative) + public E getFixed(String id, boolean creative) { - return this.get(oid, creative, true); + return this.getFixed(id, creative, true); } - protected E get(Object oid, boolean creative, boolean noteModification) + protected E getFixed(String id, boolean creative, boolean noteModification) { - String id = this.fixId(oid); if (id == null) return null; E ret = this.id2entity.get(id); if (ret != null) return ret; @@ -127,9 +121,8 @@ public class Coll implements CollInterface @Override public Collection getIds() { return Collections.unmodifiableCollection(this.id2entity.keySet()); } @Override public Collection getIdsRemote() { return this.getDb().getIds(this); } @Override - public boolean containsId(Object oid) + public boolean containsIdFixed(String id) { - String id = this.fixId(oid); if (id == null) return false; return this.id2entity.containsKey(id); } @@ -153,14 +146,8 @@ public class Coll implements CollInterface if (oid == null) return null; String ret = null; - if (oid instanceof String) - { - ret = (String)oid; - } - else if (oid.getClass() == this.entityClass) - { - ret = this.entity2id.get(oid); - } + if (oid instanceof String) ret = (String) oid; + else if (oid.getClass() == this.getEntityClass()) ret = this.entity2id.get(oid); if (ret == null) return null; return this.isLowercasing() ? ret.toLowerCase() : ret; @@ -233,12 +220,14 @@ public class Coll implements CollInterface // This simply creates and returns a new instance // It does not detach/attach or anything. Just creates a new instance. + // TODO: Would it ever make sense for this to fail? + // Should we just throw an exception immediately if it fails? @Override public E createNewInstance() { try { - return this.entityClass.newInstance(); + return this.getEntityClass().newInstance(); } catch (Exception e) { @@ -246,13 +235,6 @@ public class Coll implements CollInterface } } - // Create new instance with automatic id - @Override - public E create() - { - return this.create(null); - } - // Create new instance with the requested id @Override public synchronized E create(Object oid) @@ -272,13 +254,7 @@ public class Coll implements CollInterface // -------------------------------------------- // @Override - public String attach(E entity) - { - return this.attach(entity, null); - } - - @Override - public synchronized String attach(E entity, Object oid) + public String attach(E entity, Object oid) { return this.attach(entity, oid, true); } @@ -288,9 +264,10 @@ public class Coll implements CollInterface { // Check entity if (entity == null) return null; - String id = this.getId(entity); - if (id != null) return id; + String previousEntityId = this.getId(entity); + if (previousEntityId != null) return previousEntityId; + String id; // Check/Fix id if (oid == null) { @@ -344,24 +321,23 @@ public class Coll implements CollInterface return e; } - this.detach(e, id); + this.detachFixed(e, id); return e; } @Override - public E detachId(Object oid) + public E detachIdFixed(String id) { - if (oid == null) throw new NullPointerException("oid"); + if (id == null) throw new NullPointerException("id"); - String id = this.fixId(oid); E e = this.get(id, false); if (e == null) return null; - this.detach(e, id); + this.detachFixed(e, id); return e; } - private void detach(E entity, String id) + private void detachFixed(E entity, String id) { if (entity == null) throw new NullPointerException("entity"); if (id == null) throw new NullPointerException("id"); @@ -370,7 +346,7 @@ public class Coll implements CollInterface this.preDetach(entity, id); // Remove @ local - this.removeAtLocal(id); + this.removeAtLocalFixed(id); // Identify Modification this.identifiedModifications.put(id, Modification.LOCAL_DETACH); @@ -421,10 +397,9 @@ public class Coll implements CollInterface protected Map identifiedModifications; - protected synchronized void removeIdentifiedModification(Object oid) + protected synchronized void removeIdentifiedModificationFixed(String id) { - if (oid == null) throw new NullPointerException("oid"); - String id = this.fixId(oid); + if (id == null) throw new NullPointerException("id"); this.identifiedModifications.remove(id); } @@ -437,11 +412,10 @@ public class Coll implements CollInterface protected Map lastRaw; protected Set lastDefault; - protected synchronized void clearSynclog(Object oid) + protected synchronized void clearSynclogFixed(String id) { - if (oid == null) throw new NullPointerException("oid"); + if (id == null) throw new NullPointerException("id"); - String id = this.fixId(oid); this.lastMtime.remove(id); this.lastRaw.remove(id); this.lastDefault.remove(id); @@ -451,21 +425,24 @@ public class Coll implements CollInterface private Map id2out = new TreeMap(); private Map id2in = new TreeMap(); + @Override public Map getSyncMap(boolean in) { return in ? this.id2in : this.id2out; } - public long getSyncCount(String id, boolean in) + @Override + public long getSyncCountFixed(String id, boolean in) { Long count = this.getSyncMap(in).get(id); if (count == null) return 0; return count; } - public void addSyncCount(String id, boolean in) + @Override + public void addSyncCountFixed(String id, boolean in) { - long count = this.getSyncCount(id, in); + long count = this.getSyncCountFixed(id, in); count++; this.getSyncMap(in).put(id, count); } @@ -476,14 +453,12 @@ public class Coll implements CollInterface @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public synchronized E removeAtLocal(Object oid) + public synchronized E removeAtLocalFixed(String id) { - // Fix Id - if (oid == null) throw new NullPointerException("oid"); - String id = this.fixId(oid); + if (id == null) throw new NullPointerException("id"); - this.removeIdentifiedModification(id); - this.clearSynclog(id); + this.removeIdentifiedModificationFixed(id); + this.clearSynclogFixed(id); E entity = this.id2entity.remove(id); if (entity == null) return null; @@ -501,27 +476,23 @@ public class Coll implements CollInterface } @Override - public synchronized void removeAtRemote(Object oid) + public synchronized void removeAtRemoteFixed(String id) { - // Fix Id - if (oid == null) throw new NullPointerException("oid"); - String id = this.fixId(oid); + if (id == null) throw new NullPointerException("id"); - this.removeIdentifiedModification(id); - this.clearSynclog(id); + this.removeIdentifiedModificationFixed(id); + this.clearSynclogFixed(id); this.getDb().delete(this, id); } @Override - public synchronized void saveToRemote(Object oid) + public synchronized void saveToRemoteFixed(String id) { - // Fix Id - if (oid == null) throw new NullPointerException("oid"); - String id = this.fixId(oid); + if (id == null) throw new NullPointerException("id"); - this.removeIdentifiedModification(id); - this.clearSynclog(id); + this.removeIdentifiedModificationFixed(id); + this.clearSynclogFixed(id); E entity = this.id2entity.get(id); if (entity == null) return; @@ -544,13 +515,11 @@ public class Coll implements CollInterface @SuppressWarnings("unchecked") @Override - public synchronized void loadFromRemote(Object oid, Entry remoteEntry) + public synchronized void loadFromRemoteFixed(String id, Entry remoteEntry) { - // Fix Id - if (oid == null) throw new NullPointerException("oid"); - String id = this.fixId(oid); + if (id == null) throw new NullPointerException("id"); - this.removeIdentifiedModification(id); + this.removeIdentifiedModificationFixed(id); if (remoteEntry == null) { @@ -636,22 +605,9 @@ public class Coll implements CollInterface // -------------------------------------------- // @Override - public Modification examineId(Object oid) + public Modification examineIdFixed(String id, Long remoteMtime) { - // Fix Id - if (oid == null) throw new NullPointerException("oid"); - //String id = this.fixId(oid); // Was done twice - - return this.examineId(oid, null); - } - - @Override - public Modification examineId(Object oid, Long remoteMtime) - { - // Fix Id - if (oid == null) throw new NullPointerException("oid"); - String id = this.fixId(oid); - + if (id == null) throw new NullPointerException("id"); // Local Attach and Detach has the top priority. // Otherwise newly attached entities would be removed thinking it was a remote detach. // Otherwise newly detached entities would be loaded thinking it was a remote attach. @@ -680,13 +636,13 @@ public class Coll implements CollInterface Long lastMtime = this.lastMtime.get(id); if (remoteMtime.equals(lastMtime) == false) return Modification.REMOTE_ALTER; - if (this.examineHasLocalAlter(id, localEntity)) return Modification.LOCAL_ALTER; + if (this.examineHasLocalAlterFixed(id, localEntity)) return Modification.LOCAL_ALTER; } else if (existsLocal) { if (this.lastDefault.contains(id)) { - if (this.examineHasLocalAlter(id, localEntity)) return Modification.LOCAL_ALTER; + if (this.examineHasLocalAlterFixed(id, localEntity)) return Modification.LOCAL_ALTER; } else { @@ -701,7 +657,7 @@ public class Coll implements CollInterface return Modification.NONE; } - protected boolean examineHasLocalAlter(String id, E entity) + protected boolean examineHasLocalAlterFixed(String id, E entity) { JsonElement lastRaw = this.lastRaw.get(id); JsonElement currentRaw = null; @@ -721,32 +677,17 @@ public class Coll implements CollInterface return !MStore.equal(lastRaw, currentRaw); } - + @Override - public Modification syncId(Object oid) + public Modification syncIdFixed(String id, Modification modification, Entry remoteEntry) { - return this.syncId(oid, null); - } - - @Override - public Modification syncId(Object oid, Modification modification) - { - return this.syncId(oid, modification, null); - } - - @Override - public Modification syncId(Object oid, Modification modification, Entry remoteEntry) - { - // Fix Id - if (oid == null) throw new NullPointerException("oid"); - String id = this.fixId(oid); - + if (id == null) throw new NullPointerException("id"); if (modification == null || modification == Modification.UNKNOWN) { Long remoteMtime = null; if (remoteEntry != null) remoteMtime = remoteEntry.getValue(); - modification = this.examineId(id, remoteMtime); + modification = this.examineIdFixed(id, remoteMtime); } // DEBUG @@ -756,40 +697,40 @@ public class Coll implements CollInterface { case LOCAL_ALTER: case LOCAL_ATTACH: - this.saveToRemote(id); + this.saveToRemoteFixed(id); if (this.inited()) { - this.addSyncCount(TOTAL, false); - this.addSyncCount(id, false); + this.addSyncCountFixed(TOTAL, false); + this.addSyncCountFixed(id, false); } break; case LOCAL_DETACH: - this.removeAtRemote(id); + this.removeAtRemoteFixed(id); if (this.inited()) { - this.addSyncCount(TOTAL, false); - this.addSyncCount(id, false); + this.addSyncCountFixed(TOTAL, false); + this.addSyncCountFixed(id, false); } break; case REMOTE_ALTER: case REMOTE_ATTACH: - this.loadFromRemote(id, remoteEntry); + this.loadFromRemoteFixed(id, remoteEntry); if (this.inited()) { - this.addSyncCount(TOTAL, true); - this.addSyncCount(id, true); + this.addSyncCountFixed(TOTAL, true); + this.addSyncCountFixed(id, true); } break; case REMOTE_DETACH: - this.removeAtLocal(id); + this.removeAtLocalFixed(id); if (this.inited()) { - this.addSyncCount(TOTAL, true); - this.addSyncCount(id, true); + this.addSyncCountFixed(TOTAL, true); + this.addSyncCountFixed(id, true); } break; default: - this.removeIdentifiedModification(id); + this.removeIdentifiedModificationFixed(id); break; } @@ -813,7 +754,7 @@ public class Coll implements CollInterface Long remoteMtime = id2RemoteMtime.get(id); if (remoteMtime == null) remoteMtime = 0L; - Modification modification = this.examineId(id, remoteMtime); + Modification modification = this.examineIdFixed(id, remoteMtime); if (modification.isModified()) { this.identifiedModifications.put(id, modification); @@ -832,7 +773,7 @@ public class Coll implements CollInterface { modification = null; } - this.syncId(id, modification); + this.syncIdFixed(id, modification); } } @@ -910,10 +851,9 @@ public class Coll implements CollInterface this.lastRaw = new ConcurrentHashMap(); this.lastDefault = Collections.newSetFromMap(new ConcurrentHashMap()); - final Coll me = this; this.tickTask = new Runnable() { - @Override public void run() { me.onTick(); } + @Override public void run() { Coll.this.onTick(); } }; } @@ -930,7 +870,7 @@ public class Coll implements CollInterface @Override public void init() { - if (this.inited()) return; + if (this.inited()) return; // TODO: Would throwing an exception make more sense? this.initLoadAllFromRemote(); // this.syncAll(); @@ -941,7 +881,7 @@ public class Coll implements CollInterface @Override public void deinit() { - if ( ! this.inited()) return; + if ( ! this.inited()) return; // TODO: Would throwing an exception make more sense? // TODO: Save outwards only? We may want to avoid loads at this stage... this.syncAll(); @@ -954,4 +894,5 @@ public class Coll implements CollInterface { return name2instance.containsKey(this.getName()); } + } diff --git a/src/com/massivecraft/massivecore/store/CollAbstract.java b/src/com/massivecraft/massivecore/store/CollAbstract.java new file mode 100644 index 00000000..a377b97c --- /dev/null +++ b/src/com/massivecraft/massivecore/store/CollAbstract.java @@ -0,0 +1,198 @@ +package com.massivecraft.massivecore.store; + +import java.util.Map.Entry; + +import com.massivecraft.massivecore.xlib.gson.JsonElement; + + +public abstract class CollAbstract implements CollInterface +{ + // -------------------------------------------- // + // WHAT DO WE HANDLE? + // -------------------------------------------- // + // This is all placed in the implementation. + + // -------------------------------------------- // + // SUPPORTING SYSTEM + // -------------------------------------------- // + // This is all placed in the implementation. + + // -------------------------------------------- // + // STORAGE + // -------------------------------------------- // + + @Override + public E get(Object oid) + { + return this.getFixed(this.fixId(oid)); + } + + @Override + public E get(Object oid, boolean creative) + { + return this.getFixed(this.fixId(oid), creative); + } + + @Override + public E getFixed(String id) + { + return this.getFixed(id, this.isCreative()); + } + + @Override + public boolean containsId(Object oid) + { + return this.containsIdFixed(this.fixId(oid)); + } + + @Override + public String fixIdOrThrow(Object oid) throws IllegalArgumentException + { + String ret = this.fixId(oid); + if (ret == null) throw new IllegalArgumentException(String.valueOf(oid) + " is not a valid id."); + return ret; + } + + // -------------------------------------------- // + // BEHAVIOR + // -------------------------------------------- // + // This is all placed in the implementation. + + // -------------------------------------------- // + // COPY AND CREATE + // -------------------------------------------- // + + // Create new instance with automatic id + @Override + public E create() + { + return this.create(null); + } + + // -------------------------------------------- // + // ATTACH AND DETACH + // -------------------------------------------- // + + @Override + public String attach(E entity) + { + return this.attach(entity, null); + } + + @Override + public E detachId(Object oid) + { + if (oid == null) throw new NullPointerException("oid"); + return this.detachIdFixed(this.fixIdOrThrow(oid)); + } + + // -------------------------------------------- // + // SYNC LOG + // -------------------------------------------- // + // This is all in the implementation. + + // -------------------------------------------- // + // SYNC LOWLEVEL IO ACTIONS + // -------------------------------------------- // + + @Override + public E removeAtLocal(Object oid) + { + if (oid == null) throw new NullPointerException("oid"); + return this.removeAtLocalFixed(this.fixIdOrThrow(oid)); + } + + @Override + public void removeAtRemote(Object oid) + { + if (oid == null) throw new NullPointerException("oid"); + this.removeAtRemoteFixed(this.fixIdOrThrow(oid)); + } + + @Override + public void saveToRemote(Object oid) + { + if (oid == null) throw new NullPointerException("oid"); + this.saveToRemoteFixed(this.fixIdOrThrow(oid)); + } + + @Override + public void loadFromRemote(Object oid, Entry remoteEntry) + { + if (oid == null) throw new NullPointerException("oid"); + this.loadFromRemoteFixed(this.fixIdOrThrow(oid), remoteEntry); + } + + // -------------------------------------------- // + // SYNC EXAMINE AND DO + // -------------------------------------------- // + + // Examine + @Override + public Modification examineId(Object oid) + { + if (oid == null) throw new NullPointerException("oid"); + return this.examineIdFixed(this.fixIdOrThrow(oid)); + } + + @Override + public Modification examineId(Object oid, Long remoteMtime) + { + if (oid == null) throw new NullPointerException("oid"); + return this.examineIdFixed(this.fixIdOrThrow(oid), remoteMtime); + } + + @Override + public Modification examineIdFixed(String id) + { + // Null check done later. + return this.examineIdFixed(id, null); + } + + // Sync + @Override + public Modification syncId(Object oid) + { + if (oid == null) throw new NullPointerException("oid"); + return this.syncIdFixed(this.fixIdOrThrow(oid)); + } + + @Override + public Modification syncId(Object oid, Modification modificationState) + { + if (oid == null) throw new NullPointerException("oid"); + return this.syncIdFixed(this.fixIdOrThrow(oid), modificationState); + } + + @Override + public Modification syncId(Object oid, Modification modificationState, Entry remoteEntry) + { + if (oid == null) throw new NullPointerException("oid"); + return this.syncIdFixed(this.fixIdOrThrow(oid), modificationState, remoteEntry); + } + + @Override + public Modification syncIdFixed(String id) + { + // Null check done later. + return this.syncIdFixed(id, null); + } + + @Override + public Modification syncIdFixed(String id, Modification modification) + { + // Null check done later. + return this.syncIdFixed(id, modification, null); + } + + // -------------------------------------------- // + // SYNC RUNNABLES / SCHEDULING + // -------------------------------------------- // + // This is all in the implementation + + // -------------------------------------------- // + // CONSTRUCT + // -------------------------------------------- // + // This is all in the implementation; + +} diff --git a/src/com/massivecraft/massivecore/store/CollInterface.java b/src/com/massivecraft/massivecore/store/CollInterface.java index e2f85177..6d84d672 100644 --- a/src/com/massivecraft/massivecore/store/CollInterface.java +++ b/src/com/massivecraft/massivecore/store/CollInterface.java @@ -35,9 +35,12 @@ public interface CollInterface public Map getId2entity(); public E get(Object oid); public E get(Object oid, boolean creative); + public E getFixed(String id); + public E getFixed(String id, boolean creative); public Collection getIds(); public Collection getIdsRemote(); public boolean containsId(Object oid); + public boolean containsIdFixed(String id); public Map getEntity2id(); public String getId(Object entity); @@ -49,6 +52,7 @@ public interface CollInterface public List getAll(Predictate where, Comparator orderby, Integer limit, Integer offset); public String fixId(Object oid); + public String fixIdOrThrow(Object oid) throws IllegalArgumentException; // -------------------------------------------- // // BEHAVIOR @@ -88,6 +92,7 @@ public interface CollInterface public E detachEntity(Object entity); public E detachId(Object oid); + public E detachIdFixed(String id); public void preAttach(E entity, String id); public void postAttach(E entity, String id); @@ -118,28 +123,47 @@ public interface CollInterface */ public Map getSyncMap(boolean in); - public long getSyncCount(String name, boolean in); - public void addSyncCount(String name, boolean in); + public long getSyncCountFixed(String name, boolean in); + public void addSyncCountFixed(String name, boolean in); // -------------------------------------------- // // SYNC LOWLEVEL IO ACTIONS // -------------------------------------------- // + // oid public E removeAtLocal(Object oid); public void removeAtRemote(Object oid); public void saveToRemote(Object oid); public void loadFromRemote(Object oid, Entry remoteEntry); + // Fixed id + public E removeAtLocalFixed(String id); + public void removeAtRemoteFixed(String id); + public void saveToRemoteFixed(String id); + public void loadFromRemoteFixed(String id, Entry remoteEntry); + // -------------------------------------------- // // SYNC EXAMINE AND DO // -------------------------------------------- // + // oid public Modification examineId(Object oid); public Modification examineId(Object oid, Long remoteMtime); + // Fixed id + public Modification examineIdFixed(String id); + public Modification examineIdFixed(String id, Long remoteMtime); + + // oid public Modification syncId(Object oid); public Modification syncId(Object oid, Modification modificationState); public Modification syncId(Object oid, Modification modificationState, Entry remoteEntry); + + // fixed id + public Modification syncIdFixed(String id); + public Modification syncIdFixed(String id, Modification modificationState); + public Modification syncIdFixed(String id, Modification modificationState, Entry remoteEntry); + public void syncIdentified(boolean safe); public void syncAll(); public void identifyModifications(); @@ -161,5 +185,4 @@ public interface CollInterface public void deinit(); public boolean inited(); - -} \ No newline at end of file +} diff --git a/src/com/massivecraft/massivecore/store/SenderColl.java b/src/com/massivecraft/massivecore/store/SenderColl.java index a768f833..656fe447 100644 --- a/src/com/massivecraft/massivecore/store/SenderColl.java +++ b/src/com/massivecraft/massivecore/store/SenderColl.java @@ -148,27 +148,32 @@ public class SenderColl> extends Coll implements Se // GET ALL ONLINE / OFFLINE // -------------------------------------------- // - // TODO: Stop mkaing a new predicate everytime. + public static final Predictate> PREDICTATE_ONLINE = new Predictate>() + { + @Override + public boolean apply(SenderEntity entity) + { + return entity.isOnline(); + } + }; + + public static final Predictate> PREDICTATE_OFFLINE = new Predictate>() + { + @Override + public boolean apply(SenderEntity entity) + { + return entity.isOffline(); + } + }; + public Collection getAllOnline() { - return this.getAll(new Predictate() - { - public boolean apply(E entity) - { - return entity.isOnline(); - } - }); + return this.getAll(PREDICTATE_ONLINE); } public Collection getAllOffline() { - return this.getAll(new Predictate() - { - public boolean apply(E entity) - { - return entity.isOffline(); - } - }); + return this.getAll(PREDICTATE_OFFLINE); } // -------------------------------------------- //