Polish databse

This commit is contained in:
BuildTools 2015-11-20 21:54:01 +01:00 committed by Olof Larsson
parent 706cdab884
commit 2a62bba658
12 changed files with 166 additions and 112 deletions

View File

@ -14,7 +14,7 @@ import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.Db; import com.massivecraft.massivecore.store.Db;
import com.massivecraft.massivecore.store.Entity; import com.massivecraft.massivecore.store.Entity;
import com.massivecraft.massivecore.store.MStore; import com.massivecraft.massivecore.store.MStore;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
public class CmdMassiveCoreStoreCopydb extends MassiveCommand public class CmdMassiveCoreStoreCopydb extends MassiveCommand
{ {
@ -88,7 +88,7 @@ public class CmdMassiveCoreStoreCopydb extends MassiveCommand
for (String id : ids) for (String id : ids)
{ {
Entry<JsonElement, Long> data = fromDb.load(fromColl, id); Entry<JsonObject, Long> data = fromDb.load(fromColl, id);
toDb.save(toColl, id, data.getKey()); toDb.save(toColl, id, data.getKey());
} }
} }

View File

@ -19,9 +19,9 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result; import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result;
import org.bukkit.event.player.PlayerChatTabCompleteEvent;
import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerChatTabCompleteEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
@ -48,7 +48,7 @@ import com.massivecraft.massivecore.store.SenderColl;
import com.massivecraft.massivecore.util.IdUtil; import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.SmokeUtil; import com.massivecraft.massivecore.util.SmokeUtil;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
public class EngineMassiveCoreMain extends EngineAbstract public class EngineMassiveCoreMain extends EngineAbstract
{ {
@ -379,13 +379,13 @@ public class EngineMassiveCoreMain extends EngineAbstract
// This section handles the automatic sync of a players corresponding massive store entries on login. // This section handles the automatic sync of a players corresponding massive store entries on login.
// If possible the database IO is made during the AsyncPlayerPreLoginEvent to offloat the main server thread. // If possible the database IO is made during the AsyncPlayerPreLoginEvent to offloat the main server thread.
protected Map<String, Map<SenderColl<?>, Entry<JsonElement, Long>>> idToRemoteEntries = new ConcurrentHashMap<String, Map<SenderColl<?>, Entry<JsonElement, Long>>>(); protected Map<String, Map<SenderColl<?>, Entry<JsonObject, Long>>> idToRemoteEntries = new ConcurrentHashMap<>();
// Intended to be ran asynchronously. // Intended to be ran asynchronously.
public void storeRemoteEntries(final String playerId) public void storeRemoteEntries(final String playerId)
{ {
// Create remote entries ... // Create remote entries ...
Map<SenderColl<?>, Entry<JsonElement, Long>> remoteEntries = createRemoteEntries(playerId); Map<SenderColl<?>, Entry<JsonObject, Long>> remoteEntries = createRemoteEntries(playerId);
// ... store them ... // ... store them ...
this.idToRemoteEntries.put(playerId, remoteEntries); this.idToRemoteEntries.put(playerId, remoteEntries);
@ -407,10 +407,10 @@ public class EngineMassiveCoreMain extends EngineAbstract
// Intended to be ran synchronously. // Intended to be ran synchronously.
// It will use remoteEntries from AsyncPlayerPreLoginEvent if possible. // It will use remoteEntries from AsyncPlayerPreLoginEvent if possible.
// If no such remoteEntries are available it will create them and thus lock the main server thread a bit. // If no such remoteEntries are available it will create them and thus lock the main server thread a bit.
public Map<SenderColl<?>, Entry<JsonElement, Long>> getRemoteEntries(String playerId) public Map<SenderColl<?>, Entry<JsonObject, Long>> getRemoteEntries(String playerId)
{ {
// If there are stored remote entries we used those ... // If there are stored remote entries we used those ...
Map<SenderColl<?>, Entry<JsonElement, Long>> ret = idToRemoteEntries.remove(playerId); Map<SenderColl<?>, Entry<JsonObject, Long>> ret = idToRemoteEntries.remove(playerId);
if (ret != null) return ret; if (ret != null) return ret;
// ... otherwise we create brand new ones. // ... otherwise we create brand new ones.
@ -418,15 +418,15 @@ public class EngineMassiveCoreMain extends EngineAbstract
} }
// Used by the two methods above. // Used by the two methods above.
public Map<SenderColl<?>, Entry<JsonElement, Long>> createRemoteEntries(String playerId) public Map<SenderColl<?>, Entry<JsonObject, Long>> createRemoteEntries(String playerId)
{ {
// Create Ret // Create Ret
Map<SenderColl<?>, Entry<JsonElement, Long>> ret = new HashMap<SenderColl<?>, Entry<JsonElement, Long>>(); Map<SenderColl<?>, Entry<JsonObject, Long>> ret = new HashMap<SenderColl<?>, Entry<JsonObject, Long>>();
// Fill Ret // Fill Ret
for (final SenderColl<?> coll : Coll.getSenderInstances()) for (final SenderColl<?> coll : Coll.getSenderInstances())
{ {
Entry<JsonElement, Long> remoteEntry = coll.getDb().load(coll, playerId); Entry<JsonObject, Long> remoteEntry = coll.getDb().load(coll, playerId);
ret.put(coll, remoteEntry); ret.put(coll, remoteEntry);
} }
@ -468,13 +468,13 @@ public class EngineMassiveCoreMain extends EngineAbstract
final String playerId = player.getUniqueId().toString(); final String playerId = player.getUniqueId().toString();
// ... get remote entries ... // ... get remote entries ...
Map<SenderColl<?>, Entry<JsonElement, Long>> remoteEntries = getRemoteEntries(playerId); Map<SenderColl<?>, Entry<JsonObject, Long>> remoteEntries = getRemoteEntries(playerId);
// ... and sync each of them. // ... and sync each of them.
for (Entry<SenderColl<?>, Entry<JsonElement, Long>> entry : remoteEntries.entrySet()) for (Entry<SenderColl<?>, Entry<JsonObject, Long>> entry : remoteEntries.entrySet())
{ {
SenderColl<?> coll = entry.getKey(); SenderColl<?> coll = entry.getKey();
Entry<JsonElement, Long> remoteEntry = entry.getValue(); Entry<JsonObject, Long> remoteEntry = entry.getValue();
coll.syncId(playerId, null, remoteEntry); coll.syncId(playerId, null, remoteEntry);
} }
} }

View File

@ -3,7 +3,6 @@ package com.massivecraft.massivecore.store;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -17,10 +16,12 @@ import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.MassivePlugin; import com.massivecraft.massivecore.MassivePlugin;
import com.massivecraft.massivecore.NaturalOrderComparator; import com.massivecraft.massivecore.NaturalOrderComparator;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.mixin.Mixin; import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.util.Txt;
import com.massivecraft.massivecore.xlib.gson.Gson; import com.massivecraft.massivecore.xlib.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject;
public class Coll<E extends Entity<E>> extends CollAbstract<E> public class Coll<E extends Entity<E>> extends CollAbstract<E>
{ {
@ -107,6 +108,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
return this.pusher; return this.pusher;
} }
@Override
public String getDebugName() public String getDebugName()
{ {
String ret = this.getPlugin().getName() + "::" + this.getBasename(); String ret = this.getPlugin().getName() + "::" + this.getBasename();
@ -125,7 +127,6 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
// Loaded // Loaded
protected Map<String, E> id2entity; protected Map<String, E> id2entity;
protected Map<E, String> entity2id;
@Override @Override
public String fixId(Object oid) public String fixId(Object oid)
@ -134,7 +135,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
String ret = null; String ret = null;
if (oid instanceof String) ret = (String) oid; if (oid instanceof String) ret = (String) oid;
else if (oid.getClass() == this.getEntityClass()) ret = this.entity2id.get(oid); else if (oid.getClass() == this.getEntityClass()) ret = ((Entity<?>) oid).getId();
if (ret == null) return null; if (ret == null) return null;
return this.isLowercasing() ? ret.toLowerCase() : ret; return this.isLowercasing() ? ret.toLowerCase() : ret;
@ -164,13 +165,15 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
return this.id2entity.containsKey(id); return this.id2entity.containsKey(id);
} }
@Override public Map<E, String> getEntity2id() { return Collections.unmodifiableMap(this.entity2id); } @Override
@Override public String getId(Object entity) { return this.entity2id.get(entity); } public boolean containsEntity(Object entity)
@Override public boolean containsEntity(Object entity) { return this.entity2id.containsKey(entity); }; {
return this.id2entity.containsValue(entity);
}
@Override public Collection<E> getAll() @Override public Collection<E> getAll()
{ {
return Collections.unmodifiableCollection(this.entity2id.keySet()); return Collections.unmodifiableCollection(this.id2entity.values());
} }
// -------------------------------------------- // // -------------------------------------------- //
@ -202,7 +205,8 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
// Should that instance be saved or not? // Should that instance be saved or not?
// If it is default it should not be saved. // If it is default it should not be saved.
@Override public boolean isDefault(E entity) @Override
public boolean isDefault(E entity)
{ {
return entity.isDefault(); return entity.isDefault();
} }
@ -211,14 +215,12 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
// COPY AND CREATE // COPY AND CREATE
// -------------------------------------------- // // -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" }) @Override
public void copy(E ofrom, E oto) public void copy(E efrom, E eto)
{ {
if (ofrom == null) throw new NullPointerException("ofrom"); if (efrom == null) throw new NullPointerException("efrom");
if (oto == null) throw new NullPointerException("oto"); if (eto == null) throw new NullPointerException("eto");
Entity efrom = (Entity)ofrom;
Entity eto = (Entity)oto;
eto.load(efrom); eto.load(efrom);
} }
@ -267,7 +269,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
{ {
// Check entity // Check entity
if (entity == null) return null; if (entity == null) return null;
String previousEntityId = this.getId(entity); String previousEntityId = entity.getId();
if (previousEntityId != null) return previousEntityId; if (previousEntityId != null) return previousEntityId;
String id; String id;
@ -292,7 +294,6 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
// Attach // Attach
this.id2entity.put(id, entity); this.id2entity.put(id, entity);
this.entity2id.put(entity, id);
// Identify Modification // Identify Modification
if (noteModification) if (noteModification)
@ -311,7 +312,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
{ {
if (entity == null) throw new NullPointerException("entity"); if (entity == null) throw new NullPointerException("entity");
String id = this.getId(entity); String id = entity.getId();
if (id == null) if (id == null)
{ {
// It seems the entity is already detached. // It seems the entity is already detached.
@ -383,6 +384,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
protected Map<String, Modification> identifiedModifications; protected Map<String, Modification> identifiedModifications;
@Override
public synchronized void putIdentifiedModificationFixed(String id, Modification modification) public synchronized void putIdentifiedModificationFixed(String id, Modification modification)
{ {
if (id == null) throw new NullPointerException("id"); if (id == null) throw new NullPointerException("id");
@ -392,7 +394,8 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
this.identifiedModifications.put(id, modification); this.identifiedModifications.put(id, modification);
} }
protected synchronized void removeIdentifiedModificationFixed(String id) @Override
public synchronized void removeIdentifiedModificationFixed(String id)
{ {
if (id == null) throw new NullPointerException("id"); if (id == null) throw new NullPointerException("id");
this.identifiedModifications.remove(id); this.identifiedModifications.remove(id);
@ -443,8 +446,6 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
if (entity == null) return null; if (entity == null) return null;
entity.clearSyncLogFields(); entity.clearSyncLogFields();
this.entity2id.remove(entity);
// Remove entity reference info // Remove entity reference info
entity.setColl(null); entity.setColl(null);
entity.setId(null); entity.setId(null);
@ -474,7 +475,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
if (entity == null) return; if (entity == null) return;
entity.clearSyncLogFields(); entity.clearSyncLogFields();
JsonElement raw = this.getGson().toJsonTree(entity, this.getEntityClass()); JsonObject raw = this.getGson().toJsonTree(entity, this.getEntityClass()).getAsJsonObject();
entity.setLastRaw(raw); entity.setLastRaw(raw);
if (this.isDefault(entity)) if (this.isDefault(entity))
@ -494,7 +495,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
} }
@Override @Override
public synchronized void loadFromRemoteFixed(String id, Entry<JsonElement, Long> remoteEntry) public synchronized void loadFromRemoteFixed(String id, Entry<JsonObject, Long> remoteEntry)
{ {
if (id == null) throw new NullPointerException("id"); if (id == null) throw new NullPointerException("id");
@ -513,7 +514,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
} }
} }
JsonElement raw = remoteEntry.getKey(); JsonObject raw = remoteEntry.getKey();
Long mtime = remoteEntry.getValue(); Long mtime = remoteEntry.getValue();
if ( ! this.remoteEntryIsOk(id, remoteEntry)) return; if ( ! this.remoteEntryIsOk(id, remoteEntry)) return;
@ -542,7 +543,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
entity.setLastDefault(false); entity.setLastDefault(false);
} }
public boolean remoteEntryIsOk(String id, Entry<JsonElement, Long> remoteEntry) public boolean remoteEntryIsOk(String id, Entry<JsonObject, Long> remoteEntry)
{ {
Long mtime = remoteEntry.getValue(); Long mtime = remoteEntry.getValue();
if (mtime == null) if (mtime == null)
@ -557,7 +558,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
return false; return false;
} }
JsonElement raw = remoteEntry.getKey(); JsonObject raw = remoteEntry.getKey();
if (raw == null) if (raw == null)
{ {
this.logLoadError(id, "Raw data was null. Is the file completely empty?"); this.logLoadError(id, "Raw data was null. Is the file completely empty?");
@ -711,12 +712,12 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
protected boolean examineHasLocalAlterFixed(String id, E entity) protected boolean examineHasLocalAlterFixed(String id, E entity)
{ {
JsonElement lastRaw = entity.getLastRaw(); JsonObject lastRaw = entity.getLastRaw();
JsonElement currentRaw = null; JsonObject currentRaw = null;
try try
{ {
currentRaw = this.getGson().toJsonTree(entity); currentRaw = this.getGson().toJsonTree(entity, this.getEntityClass()).getAsJsonObject();
} }
catch (Exception e) catch (Exception e)
{ {
@ -731,7 +732,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
} }
@Override @Override
public Modification syncIdFixed(String id, Modification modification, Entry<JsonElement, Long> remoteEntry) public Modification syncIdFixed(String id, Modification modification, Entry<JsonObject, Long> remoteEntry)
{ {
if (id == null) throw new NullPointerException("id"); if (id == null) throw new NullPointerException("id");
if (modification == null || modification == Modification.UNKNOWN) if (modification == null || modification == Modification.UNKNOWN)
@ -884,9 +885,12 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
if (this.isWarningOnLocalAlter() && modification == Modification.LOCAL_ALTER) if (this.isWarningOnLocalAlter() && modification == Modification.LOCAL_ALTER)
{ {
MassiveCore.get().log( MassiveCore.get().log(
"A local alter was made in " + this.getName() + " on " + id, "A local alter was spotted in " + this.getDebugName() + " on " + id
"This was unintended, the developers should be informed."
); );
E entity = this.get(id);
JsonObject lastRaw = entity.getLastRaw();
JsonObject currentRaw = this.getGson().toJsonTree(entity, this.getEntityClass()).getAsJsonObject();
this.logModification(lastRaw, currentRaw);
} }
if (modification.isModified()) if (modification.isModified())
@ -897,6 +901,40 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
} }
} }
protected void logModification(JsonObject lastRaw, JsonObject currentRaw)
{
List<String> changes = new MassiveList<>();
// Check removal and modification.
for (Entry<String, JsonElement> entry : lastRaw.entrySet())
{
String name = entry.getKey();
JsonElement currentValue = currentRaw.get(name);
if (currentValue == null)
{
changes.add(String.format("Removed %s", name));
continue;
}
JsonElement lastValue = entry.getValue();
if (MStore.equal(currentValue, lastValue)) return;
changes.add(String.format("Changed %s: %s -> %s", name, lastValue, currentValue));
}
// Check for addition
for (Entry<String, JsonElement> entry : currentRaw.entrySet())
{
String name = entry.getKey();
if (lastRaw.has(name)) continue;
changes.add(String.format("Added %s: %s", name, entry.getValue()));
}
// Log
for (String change : changes)
{
MassiveCore.get().log(change);
}
}
@Override @Override
public void syncIdentified() public void syncIdentified()
{ {
@ -918,13 +956,13 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
@Override @Override
public void initLoadAllFromRemote() public void initLoadAllFromRemote()
{ {
Map<String, Entry<JsonElement, Long>> idToEntryMap = this.getDb().loadAll(this); Map<String, Entry<JsonObject, Long>> idToEntryMap = this.getDb().loadAll(this);
if (idToEntryMap == null) return; if (idToEntryMap == null) return;
for (Entry<String, Entry<JsonElement, Long>> idToEntry : idToEntryMap.entrySet()) for (Entry<String, Entry<JsonObject, Long>> idToEntry : idToEntryMap.entrySet())
{ {
String id = idToEntry.getKey(); String id = idToEntry.getKey();
Entry<JsonElement, Long> remoteEntry = idToEntry.getValue(); Entry<JsonObject, Long> remoteEntry = idToEntry.getValue();
loadFromRemoteFixed(id, remoteEntry); loadFromRemoteFixed(id, remoteEntry);
} }
} }
@ -972,7 +1010,6 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
// STORAGE // STORAGE
this.id2entity = (sorted) ? new ConcurrentSkipListMap<String, E>(NaturalOrderComparator.get()) : new ConcurrentHashMap<String, E>(); this.id2entity = (sorted) ? new ConcurrentSkipListMap<String, E>(NaturalOrderComparator.get()) : new ConcurrentHashMap<String, E>();
this.entity2id = (Entity.class.isAssignableFrom(entityClass) && sorted) ? new ConcurrentSkipListMap<E, String>((Comparator<? super E>) ComparatorEntityId.get()) : new ConcurrentHashMap<E, String>();
// ENTITY DATA // ENTITY DATA
this.identifiedModifications = new ConcurrentHashMap<String, Modification>(); this.identifiedModifications = new ConcurrentHashMap<String, Modification>();
@ -995,7 +1032,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
if (this.supportsPusher()) if (this.supportsPusher())
{ {
//this.getPusher().init(); this.getPusher().init();
} }
this.initLoadAllFromRemote(); this.initLoadAllFromRemote();
@ -1011,7 +1048,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
if (this.supportsPusher()) if (this.supportsPusher())
{ {
//this.getPusher().deinit(); this.getPusher().deinit();
} }
// TODO: Save outwards only? We may want to avoid loads at this stage... // TODO: Save outwards only? We may want to avoid loads at this stage...

View File

@ -7,7 +7,7 @@ import java.util.Map.Entry;
import com.massivecraft.massivecore.Predicate; import com.massivecraft.massivecore.Predicate;
import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
public abstract class CollAbstract<E extends Entity<E>> implements CollInterface<E> public abstract class CollAbstract<E extends Entity<E>> implements CollInterface<E>
@ -132,6 +132,24 @@ public abstract class CollAbstract<E extends Entity<E>> implements CollInterface
return this.detachIdFixed(this.fixIdOrThrow(oid)); return this.detachIdFixed(this.fixIdOrThrow(oid));
} }
// -------------------------------------------- //
// IDENTIFIED MODIFICATIONS
// -------------------------------------------- //
@Override
public void putIdentifiedModification(Object oid, Modification modification)
{
if (oid == null) throw new NullPointerException("oid");
this.putIdentifiedModificationFixed(this.fixIdOrThrow(oid), modification);
}
@Override
public void removeIdentifiedModification(Object oid)
{
if (oid == null) throw new NullPointerException("oid");
this.removeIdentifiedModificationFixed(this.fixIdOrThrow(oid));
}
// -------------------------------------------- // // -------------------------------------------- //
// SYNC LOG // SYNC LOG
// -------------------------------------------- // // -------------------------------------------- //
@ -163,7 +181,7 @@ public abstract class CollAbstract<E extends Entity<E>> implements CollInterface
} }
@Override @Override
public void loadFromRemote(Object oid, Entry<JsonElement, Long> remoteEntry) public void loadFromRemote(Object oid, Entry<JsonObject, Long> remoteEntry)
{ {
if (oid == null) throw new NullPointerException("oid"); if (oid == null) throw new NullPointerException("oid");
this.loadFromRemoteFixed(this.fixIdOrThrow(oid), remoteEntry); this.loadFromRemoteFixed(this.fixIdOrThrow(oid), remoteEntry);
@ -241,7 +259,7 @@ public abstract class CollAbstract<E extends Entity<E>> implements CollInterface
} }
@Override @Override
public Modification syncId(Object oid, Modification modification, Entry<JsonElement, Long> remoteEntry) public Modification syncId(Object oid, Modification modification, Entry<JsonObject, Long> remoteEntry)
{ {
if (oid == null) throw new NullPointerException("oid"); if (oid == null) throw new NullPointerException("oid");
return this.syncIdFixed(this.fixIdOrThrow(oid), modification, remoteEntry); return this.syncIdFixed(this.fixIdOrThrow(oid), modification, remoteEntry);

View File

@ -10,7 +10,7 @@ import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.Named; import com.massivecraft.massivecore.Named;
import com.massivecraft.massivecore.Predicate; import com.massivecraft.massivecore.Predicate;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
public interface CollInterface<E extends Entity<E>> extends Named public interface CollInterface<E extends Entity<E>> extends Named
{ {
@ -35,6 +35,8 @@ public interface CollInterface<E extends Entity<E>> extends Named
public boolean supportsPusher(); public boolean supportsPusher();
public PusherColl getPusher(); public PusherColl getPusher();
public String getDebugName();
// -------------------------------------------- // // -------------------------------------------- //
// STORAGE // STORAGE
// -------------------------------------------- // // -------------------------------------------- //
@ -52,8 +54,6 @@ public interface CollInterface<E extends Entity<E>> extends Named
public boolean containsId(Object oid); public boolean containsId(Object oid);
public boolean containsIdFixed(String id); public boolean containsIdFixed(String id);
public Map<E, String> getEntity2id();
public String getId(Object entity);
public boolean containsEntity(Object entity); public boolean containsEntity(Object entity);
public Collection<E> getAll(); public Collection<E> getAll();
@ -139,12 +139,11 @@ public interface CollInterface<E extends Entity<E>> extends Named
// IDENTIFIED MODIFICATIONS // IDENTIFIED MODIFICATIONS
// -------------------------------------------- // // -------------------------------------------- //
/* public void putIdentifiedModification(Object oid, Modification modification);
public Set<L> localAttachIds(); public void putIdentifiedModificationFixed(String id, Modification modification);
public Set<L> localDetachIds();
public Set<L> changedIds(); public void removeIdentifiedModification(Object oid);
public void clearIdentifiedChanges(Object oid); public void removeIdentifiedModificationFixed(String id);
*/
// -------------------------------------------- // // -------------------------------------------- //
// SYNC LOG // SYNC LOG
@ -169,13 +168,13 @@ public interface CollInterface<E extends Entity<E>> extends Named
public E removeAtLocal(Object oid); public E removeAtLocal(Object oid);
public void removeAtRemote(Object oid); public void removeAtRemote(Object oid);
public void saveToRemote(Object oid); public void saveToRemote(Object oid);
public void loadFromRemote(Object oid, Entry<JsonElement, Long> remoteEntry); public void loadFromRemote(Object oid, Entry<JsonObject, Long> remoteEntry);
// Fixed id // Fixed id
public E removeAtLocalFixed(String id); public E removeAtLocalFixed(String id);
public void removeAtRemoteFixed(String id); public void removeAtRemoteFixed(String id);
public void saveToRemoteFixed(String id); public void saveToRemoteFixed(String id);
public void loadFromRemoteFixed(String id, Entry<JsonElement, Long> remoteEntry); public void loadFromRemoteFixed(String id, Entry<JsonObject, Long> remoteEntry);
// -------------------------------------------- // // -------------------------------------------- //
// SYNC EXAMINE AND DO // SYNC EXAMINE AND DO
@ -198,12 +197,12 @@ public interface CollInterface<E extends Entity<E>> extends Named
// Sync // Sync
public Modification syncId(Object oid); public Modification syncId(Object oid);
public Modification syncId(Object oid, Modification modification); public Modification syncId(Object oid, Modification modification);
public Modification syncId(Object oid, Modification modification, Entry<JsonElement, Long> remoteEntry); public Modification syncId(Object oid, Modification modification, Entry<JsonObject, Long> remoteEntry);
// Sync fixed // Sync fixed
public Modification syncIdFixed(String id); public Modification syncIdFixed(String id);
public Modification syncIdFixed(String id, Modification modification); public Modification syncIdFixed(String id, Modification modification);
public Modification syncIdFixed(String id, Modification modification, Entry<JsonElement, Long> remoteEntry); public Modification syncIdFixed(String id, Modification modification, Entry<JsonObject, Long> remoteEntry);
public void syncIdentified(); public void syncIdentified();
public void syncAll(); public void syncAll();

View File

@ -2,10 +2,10 @@ package com.massivecraft.massivecore.store;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
public interface Db public interface Db
{ {
@ -36,9 +36,9 @@ public interface Db
public long getMtime(Coll<?> coll, String id); public long getMtime(Coll<?> coll, String id);
public Collection<String> getIds(Coll<?> coll); public Collection<String> getIds(Coll<?> coll);
public Map<String, Long> getId2mtime(Coll<?> coll); public Map<String, Long> getId2mtime(Coll<?> coll);
public Entry<JsonElement, Long> load(Coll<?> coll, String id); public Entry<JsonObject, Long> load(Coll<?> coll, String id);
public Map<String, Entry<JsonElement, Long>> loadAll(Coll<?> coll); public Map<String, Entry<JsonObject, Long>> loadAll(Coll<?> coll);
public long save(Coll<?> coll, String id, JsonElement data); public long save(Coll<?> coll, String id, JsonObject data);
public void delete(Coll<?> coll, String id); public void delete(Coll<?> coll, String id);
public boolean supportsPusher(); public boolean supportsPusher();
public PusherColl getPusher(Coll<?> coll); public PusherColl getPusher(Coll<?> coll);

View File

@ -2,10 +2,10 @@ package com.massivecraft.massivecore.store;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
public abstract class DbAbstract implements Db public abstract class DbAbstract implements Db
{ {
@ -58,17 +58,17 @@ public abstract class DbAbstract implements Db
return this.getDriver().getId2mtime(coll); return this.getDriver().getId2mtime(coll);
} }
public Entry<JsonElement, Long> load(Coll<?> coll, String id) public Entry<JsonObject, Long> load(Coll<?> coll, String id)
{ {
return this.getDriver().load(coll, id); return this.getDriver().load(coll, id);
} }
public Map<String, Entry<JsonElement, Long>> loadAll(Coll<?> coll) public Map<String, Entry<JsonObject, Long>> loadAll(Coll<?> coll)
{ {
return this.getDriver().loadAll(coll); return this.getDriver().loadAll(coll);
} }
public long save(Coll<?> coll, String id, JsonElement data) public long save(Coll<?> coll, String id, JsonObject data)
{ {
return this.getDriver().save(coll, id, data); return this.getDriver().save(coll, id, data);
} }

View File

@ -5,7 +5,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
public interface Driver public interface Driver
{ {
@ -42,18 +42,18 @@ public interface Driver
// Load the raw data for X. The second part of the entry is the remote mtime at the load. // Load the raw data for X. The second part of the entry is the remote mtime at the load.
// return == null will never happen. // return == null will never happen.
// return.getKey() == null || return.getValue() == 0 means something failed. // return.getKey() == null || return.getValue() == 0 means something failed.
public Entry<JsonElement, Long> load(Coll<?> coll, String id); public Entry<JsonObject, Long> load(Coll<?> coll, String id);
// Load all database content at once // Load all database content at once
// NOTE: This method is assumed to be based on the one above. // NOTE: This method is assumed to be based on the one above.
// NOTE: Values where JsonElement == null and Long == 0 may occur. // NOTE: Values where JsonObject == null and Long == 0 may occur.
public Map<String, Entry<JsonElement, Long>> loadAll(Coll<?> coll); public Map<String, Entry<JsonObject, Long>> loadAll(Coll<?> coll);
// Save raw data as X // Save raw data as X
// Return value is the new mtime (we caused the change). // Return value is the new mtime (we caused the change).
// return == null will never happen. // return == null will never happen.
// return == 0 means something failed. Usually failures are not catched, though. System.currentTimeMillis() is returned most of the time. // return == 0 means something failed. Usually failures are not catched, though. System.currentTimeMillis() is returned most of the time.
public long save(Coll<?> coll, String id, JsonElement data); public long save(Coll<?> coll, String id, JsonObject data);
// Delete X // Delete X
public void delete(Coll<?> coll, String id); public void delete(Coll<?> coll, String id);

View File

@ -15,7 +15,7 @@ import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import com.massivecraft.massivecore.util.DiscUtil; import com.massivecraft.massivecore.util.DiscUtil;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonParser; import com.massivecraft.massivecore.xlib.gson.JsonParser;
public class DriverFlatfile extends DriverAbstract public class DriverFlatfile extends DriverAbstract
@ -141,21 +141,21 @@ public class DriverFlatfile extends DriverAbstract
} }
@Override @Override
public Entry<JsonElement, Long> load(Coll<?> coll, String id) public Entry<JsonObject, Long> load(Coll<?> coll, String id)
{ {
File file = fileFromId(coll, id); File file = fileFromId(coll, id);
return loadFile(file); return loadFile(file);
} }
public Entry<JsonElement, Long> loadFile(File file) public Entry<JsonObject, Long> loadFile(File file)
{ {
long mtime = file.lastModified(); long mtime = file.lastModified();
JsonElement raw = loadFileJson(file); JsonObject raw = loadFileJson(file);
return new SimpleEntry<JsonElement, Long>(raw, mtime); return new SimpleEntry<JsonObject, Long>(raw, mtime);
} }
public JsonElement loadFileJson(File file) public JsonObject loadFileJson(File file)
{ {
String content = DiscUtil.readCatch(file); String content = DiscUtil.readCatch(file);
if (content == null) return null; if (content == null) return null;
@ -163,14 +163,14 @@ public class DriverFlatfile extends DriverAbstract
content = content.trim(); content = content.trim();
if (content.length() == 0) return null; if (content.length() == 0) return null;
return new JsonParser().parse(content); return new JsonParser().parse(content).getAsJsonObject();
} }
@Override @Override
public Map<String, Entry<JsonElement, Long>> loadAll(Coll<?> coll) public Map<String, Entry<JsonObject, Long>> loadAll(Coll<?> coll)
{ {
// Create Ret // Create Ret
Map<String, Entry<JsonElement, Long>> ret = null; Map<String, Entry<JsonObject, Long>> ret = null;
// Get Directory // Get Directory
File directory = getDirectory(coll); File directory = getDirectory(coll);
@ -180,7 +180,7 @@ public class DriverFlatfile extends DriverAbstract
File[] files = directory.listFiles(JsonFileFilter.get()); File[] files = directory.listFiles(JsonFileFilter.get());
// Create Ret // Create Ret
ret = new LinkedHashMap<String, Entry<JsonElement, Long>>(files.length); ret = new LinkedHashMap<String, Entry<JsonObject, Long>>(files.length);
// For Each Found // For Each Found
for (File file : files) for (File file : files)
@ -189,7 +189,7 @@ public class DriverFlatfile extends DriverAbstract
String id = idFromFile(file); String id = idFromFile(file);
// Get Entry // Get Entry
Entry<JsonElement, Long> entry = loadFile(file); Entry<JsonObject, Long> entry = loadFile(file);
// NOTE: The entry can be a failed one with null and 0. // NOTE: The entry can be a failed one with null and 0.
// NOTE: We add it anyways since it's an informative failure. // NOTE: We add it anyways since it's an informative failure.
// NOTE: This is supported by our defined specification. // NOTE: This is supported by our defined specification.
@ -203,7 +203,7 @@ public class DriverFlatfile extends DriverAbstract
} }
@Override @Override
public long save(Coll<?> coll, String id, JsonElement data) public long save(Coll<?> coll, String id, JsonObject data)
{ {
File file = fileFromId(coll, id); File file = fileFromId(coll, id);
String content = coll.getGson().toJson(data); String content = coll.getGson().toJson(data);

View File

@ -1,17 +1,17 @@
package com.massivecraft.massivecore.store; package com.massivecraft.massivecore.store;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import com.massivecraft.massivecore.MassiveCoreMConf; import com.massivecraft.massivecore.MassiveCoreMConf;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
import com.massivecraft.massivecore.xlib.mongodb.BasicDBObject; import com.massivecraft.massivecore.xlib.mongodb.BasicDBObject;
import com.massivecraft.massivecore.xlib.mongodb.DB; import com.massivecraft.massivecore.xlib.mongodb.DB;
import com.massivecraft.massivecore.xlib.mongodb.DBCollection; import com.massivecraft.massivecore.xlib.mongodb.DBCollection;
@ -171,16 +171,16 @@ public class DriverMongo extends DriverAbstract
} }
@Override @Override
public Entry<JsonElement, Long> load(Coll<?> coll, String id) public Entry<JsonObject, Long> load(Coll<?> coll, String id)
{ {
DBCollection dbcoll = fixColl(coll); DBCollection dbcoll = fixColl(coll);
BasicDBObject raw = (BasicDBObject)dbcoll.findOne(new BasicDBObject(ID_FIELD, id)); BasicDBObject raw = (BasicDBObject)dbcoll.findOne(new BasicDBObject(ID_FIELD, id));
return loadRaw(raw); return loadRaw(raw);
} }
public Entry<JsonElement, Long> loadRaw(BasicDBObject raw) public Entry<JsonObject, Long> loadRaw(BasicDBObject raw)
{ {
if (raw == null) return new SimpleEntry<JsonElement, Long>(null, 0L); if (raw == null) return new SimpleEntry<JsonObject, Long>(null, 0L);
// Throw away the id field // Throw away the id field
raw.removeField(ID_FIELD); raw.removeField(ID_FIELD);
@ -196,16 +196,16 @@ public class DriverMongo extends DriverAbstract
} }
// Convert MongoDB --> GSON // Convert MongoDB --> GSON
JsonElement element = GsonMongoConverter.mongo2GsonObject(raw); JsonObject element = GsonMongoConverter.mongo2GsonObject(raw);
return new SimpleEntry<JsonElement, Long>(element, mtime); return new SimpleEntry<JsonObject, Long>(element, mtime);
} }
@Override @Override
public Map<String, Entry<JsonElement, Long>> loadAll(Coll<?> coll) public Map<String, Entry<JsonObject, Long>> loadAll(Coll<?> coll)
{ {
// Declare Ret // Declare Ret
Map<String, Entry<JsonElement, Long>> ret = null; Map<String, Entry<JsonObject, Long>> ret = null;
// Fix Coll // Fix Coll
DBCollection dbcoll = fixColl(coll); DBCollection dbcoll = fixColl(coll);
@ -216,7 +216,7 @@ public class DriverMongo extends DriverAbstract
try try
{ {
// Create Ret // Create Ret
ret = new LinkedHashMap<String, Entry<JsonElement, Long>>(cursor.count()); ret = new LinkedHashMap<String, Entry<JsonObject, Long>>(cursor.count());
// For Each Found // For Each Found
while (cursor.hasNext()) while (cursor.hasNext())
@ -229,7 +229,7 @@ public class DriverMongo extends DriverAbstract
String id = rawId.toString(); String id = rawId.toString();
// Get Entry // Get Entry
Entry<JsonElement, Long> entry = loadRaw(raw); Entry<JsonObject, Long> entry = loadRaw(raw);
// NOTE: The entry can be a failed one with null and 0. // NOTE: The entry can be a failed one with null and 0.
// NOTE: We add it anyways since it's an informative failure. // NOTE: We add it anyways since it's an informative failure.
// NOTE: This is supported by our defined specification. // NOTE: This is supported by our defined specification.
@ -249,7 +249,7 @@ public class DriverMongo extends DriverAbstract
} }
@Override @Override
public long save(Coll<?> coll, String id, JsonElement data) public long save(Coll<?> coll, String id, JsonObject data)
{ {
DBCollection dbcoll = fixColl(coll); DBCollection dbcoll = fixColl(coll);

View File

@ -3,7 +3,7 @@ package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.store.accessor.Accessor; import com.massivecraft.massivecore.store.accessor.Accessor;
import com.massivecraft.massivecore.xlib.gson.Gson; import com.massivecraft.massivecore.xlib.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonObject;
/** /**
* Usage of this class is highly optional. You may persist anything. If you are * Usage of this class is highly optional. You may persist anything. If you are
@ -35,9 +35,9 @@ public class Entity<E extends Entity<E>>
return coll.getUniverse(); return coll.getUniverse();
} }
private volatile transient JsonElement lastRaw = null; private volatile transient JsonObject lastRaw = null;
public JsonElement getLastRaw() { return this.lastRaw; } public JsonObject getLastRaw() { return this.lastRaw; }
public void setLastRaw(JsonElement lastRaw) { this.lastRaw = lastRaw; } public void setLastRaw(JsonObject lastRaw) { this.lastRaw = lastRaw; }
private volatile transient long lastMtime = 0; private volatile transient long lastMtime = 0;
public long getLastMtime() { return this.lastMtime; } public long getLastMtime() { return this.lastMtime; }

View File

@ -78,7 +78,7 @@ public class SenderColl<E extends SenderEntity<E>> extends Coll<E> implements Se
} }
else if (oid.getClass() == this.entityClass) else if (oid.getClass() == this.entityClass)
{ {
ret = this.entity2id.get(oid); ret = ((Entity<?>) oid).getId();
} }
if (ret == null) if (ret == null)