Database improvements

Adding a modification mixin.
Merging Entity and EntityMeta
Making the use of the Entity class mandatory.
And other few tweaks.
This commit is contained in:
BuildTools 2015-11-06 15:14:14 +01:00 committed by Olof Larsson
parent b2bc9ed9ab
commit fdd530998a
18 changed files with 160 additions and 186 deletions

View File

@ -99,9 +99,7 @@ public class MassiveCoreMConf extends Entity<MassiveCoreMConf>
// MSTORE CONFIGURATON // MSTORE CONFIGURATON
// -------------------------------------------- // // -------------------------------------------- //
public volatile long millisBetweenLocalPoll = 1000; public volatile long millisBetweenLocalPoll = 5_000;
public volatile long millisBetweenLocalPollColl = 100; public volatile long millisBetweenRemotePollWithoutPusher = 5_000;
public volatile long millisBetweenRemotePollWithPusher = 30_000;
public volatile long millisBetweenRemotePoll = 1000;
public volatile long millisBetweenRemotePollColl = 100;
} }

View File

@ -12,6 +12,7 @@ import com.massivecraft.massivecore.command.requirement.RequirementHasPerm;
import com.massivecraft.massivecore.command.type.primitive.TypeString; import com.massivecraft.massivecore.command.type.primitive.TypeString;
import com.massivecraft.massivecore.store.Coll; 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.MStore; import com.massivecraft.massivecore.store.MStore;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonElement;
@ -38,6 +39,7 @@ public class CmdMassiveCoreStoreCopydb extends MassiveCommand
// OVERRIDE // OVERRIDE
// -------------------------------------------- // // -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override @Override
public void perform() throws MassiveException public void perform() throws MassiveException
{ {
@ -71,8 +73,8 @@ public class CmdMassiveCoreStoreCopydb extends MassiveCommand
for (String collname : fromDb.getCollnames()) for (String collname : fromDb.getCollnames())
{ {
countCollCurrent++; countCollCurrent++;
final Coll<?> fromColl = new Coll<Object>(collname, Object.class, fromDb, MassiveCore.get()); final Coll fromColl = new Coll(collname, Entity.class, fromDb, MassiveCore.get());
final Coll<?> toColl = new Coll<Object>(collname, Object.class, toDb, MassiveCore.get()); final Coll toColl = new Coll(collname, Entity.class, toDb, MassiveCore.get());
Collection<String> ids = fromDb.getIds(fromColl); Collection<String> ids = fromDb.getIds(fromColl);
msg("<i>Now copying collection <h>%d/%d %s <i>with <h>%d <i>documents.", countCollCurrent, countCollTotal, collname, ids.size()); msg("<i>Now copying collection <h>%d/%d %s <i>with <h>%d <i>documents.", countCollCurrent, countCollTotal, collname, ids.size());

View File

@ -216,7 +216,6 @@ public abstract class TypeAbstractChoice<T> extends TypeAbstract<T> implements A
// MATCHES // MATCHES
// -------------------------------------------- // // -------------------------------------------- //
@SuppressWarnings("unchecked")
public List<T> getMatches(Map<String, T> options, String arg, boolean levenshtein) public List<T> getMatches(Map<String, T> options, String arg, boolean levenshtein)
{ {
// Create // Create

View File

@ -16,6 +16,8 @@ import com.massivecraft.massivecore.Predicate;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave; import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
import com.massivecraft.massivecore.mson.Mson; import com.massivecraft.massivecore.mson.Mson;
import com.massivecraft.massivecore.ps.PS; import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.Entity;
import com.massivecraft.massivecore.teleport.Destination; import com.massivecraft.massivecore.teleport.Destination;
public class Mixin public class Mixin
@ -72,6 +74,10 @@ public class Mixin
public static CommandMixin getCommandMixin() { return commandMixin; } public static CommandMixin getCommandMixin() { return commandMixin; }
public static void setCommandMixin(CommandMixin val) { commandMixin = val; } public static void setCommandMixin(CommandMixin val) { commandMixin = val; }
private static ModificationMixin modificationMixin = ModificationMixinDefault.get();
public static ModificationMixin getModificationMixin() { return modificationMixin; }
public static void setModificationMixin(ModificationMixin val) { modificationMixin = val; }
// -------------------------------------------- // // -------------------------------------------- //
// STATIC EXPOSE: WORLD // STATIC EXPOSE: WORLD
// -------------------------------------------- // // -------------------------------------------- //
@ -398,4 +404,18 @@ public class Mixin
return getCommandMixin().dispatchCommand(presentObject, senderObject, commandLine); return getCommandMixin().dispatchCommand(presentObject, senderObject, commandLine);
} }
// -------------------------------------------- //
// STATIC EXPOSE: MODIFCATION
// -------------------------------------------- //
public static void syncModification(Entity<?> entity)
{
getModificationMixin().syncModification(entity);
}
public static void syncModification(Coll<?> coll, String id)
{
getModificationMixin().syncModification(coll, id);
}
} }

View File

@ -0,0 +1,10 @@
package com.massivecraft.massivecore.mixin;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.Entity;
public interface ModificationMixin
{
public void syncModification(Entity<?> entity);
public void syncModification(Coll<?> coll, String id);
}

View File

@ -0,0 +1,11 @@
package com.massivecraft.massivecore.mixin;
import com.massivecraft.massivecore.store.Entity;
public abstract class ModificationMixinAbstract implements ModificationMixin
{
public void syncModification(Entity<?> entity)
{
this.syncModification(entity.getColl(), entity.getId());
}
}

View File

@ -0,0 +1,23 @@
package com.massivecraft.massivecore.mixin;
import com.massivecraft.massivecore.store.Coll;
public class ModificationMixinDefault extends ModificationMixinAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ModificationMixinDefault i = new ModificationMixinDefault();
public static ModificationMixinDefault get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void syncModification(Coll<?> coll, String id)
{
// Nothing to do here
}
}

View File

@ -17,13 +17,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.store.accessor.Accessor; 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 CollAbstract<E> public class Coll<E extends Entity<E>> extends CollAbstract<E>
{ {
// -------------------------------------------- // // -------------------------------------------- //
// GLOBAL REGISTRY // GLOBAL REGISTRY
@ -189,9 +188,9 @@ public class Coll<E> extends CollAbstract<E>
@Override public boolean isLowercasing() { return this.lowercasing; } @Override public boolean isLowercasing() { return this.lowercasing; }
@Override public void setLowercasing(boolean lowercasing) { this.lowercasing = lowercasing; } @Override public void setLowercasing(boolean lowercasing) { this.lowercasing = lowercasing; }
protected int localPollFrequency = 5; protected int localPollInfrequency = MStore.DEFAULT_LOCAL_POLL_INFREQUENCY;
@Override public int getLocalPollFrequency() { return this.localPollFrequency; } @Override public int getLocalPollInfrequency() { return this.localPollInfrequency; }
@Override public void setLocalPollFrequency(int frequency) { this.localPollFrequency = frequency; } @Override public void setLocalPollInfrequency(int infrequence) { this.localPollInfrequency = infrequence; }
// We often try to call Entity#changed to inform that an entity has been changed locally. // We often try to call Entity#changed to inform that an entity has been changed locally.
// And on some Colls we expect it to always be done. // And on some Colls we expect it to always be done.
@ -205,14 +204,7 @@ public class Coll<E> extends CollAbstract<E>
// 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)
{ {
if (entity instanceof Entity) return entity.isDefault();
{
return ((Entity<?>)entity).isDefault();
}
else
{
return false;
}
} }
// -------------------------------------------- // // -------------------------------------------- //
@ -220,34 +212,14 @@ public class Coll<E> extends CollAbstract<E>
// -------------------------------------------- // // -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
public void copy(Object ofrom, Object oto) public void copy(E ofrom, E oto)
{ {
if (ofrom == null) throw new NullPointerException("ofrom"); if (ofrom == null) throw new NullPointerException("ofrom");
if (oto == null) throw new NullPointerException("oto"); if (oto == null) throw new NullPointerException("oto");
if (ofrom instanceof Entity) Entity efrom = (Entity)ofrom;
{ Entity eto = (Entity)oto;
Entity efrom = (Entity)ofrom; eto.load(efrom);
Entity eto = (Entity)oto;
eto.load(efrom);
}
else if (ofrom instanceof JsonObject)
{
JsonObject jfrom = (JsonObject)ofrom;
JsonObject jto = (JsonObject)oto;
// Clear To
jto.entrySet().clear();
// Copy
for (Entry<String, JsonElement> entry : jfrom.entrySet())
{
jto.add(entry.getKey(), entry.getValue());
}
}
else
{
Accessor.get(this.getEntityClass()).copy(ofrom, oto);
}
} }
// This simply creates and returns a new instance // This simply creates and returns a new instance
@ -291,7 +263,6 @@ public class Coll<E> extends CollAbstract<E>
return this.attach(entity, oid, true); return this.attach(entity, oid, true);
} }
@SuppressWarnings({ "unchecked", "rawtypes" })
protected synchronized String attach(E entity, Object oid, boolean noteModification) protected synchronized String attach(E entity, Object oid, boolean noteModification)
{ {
// Check entity // Check entity
@ -316,26 +287,19 @@ public class Coll<E> extends CollAbstract<E>
this.preAttach(entity, id); this.preAttach(entity, id);
// Add entity reference info // Add entity reference info
if (entity instanceof Entity) entity.setColl(this);
{ entity.setId(id);
((Entity)entity).setColl(this);
((Entity)entity).setId(id);
}
// Attach // Attach
this.id2entity.put(id, entity); this.id2entity.put(id, entity);
this.entity2id.put(entity, id); this.entity2id.put(entity, id);
EntityMeta meta = new EntityMeta();
// Identify Modification // Identify Modification
if (noteModification) if (noteModification)
{ {
this.identifiedModifications.put(id, Modification.LOCAL_ATTACH); this.identifiedModifications.put(id, Modification.LOCAL_ATTACH);
} }
this.metaData.put(id, meta);
// POST // POST
this.postAttach(entity, id); this.postAttach(entity, id);
@ -392,37 +356,25 @@ public class Coll<E> extends CollAbstract<E>
@Override @Override
public void preAttach(E entity, String id) public void preAttach(E entity, String id)
{ {
if (entity instanceof Entity) entity.preAttach(id);
{
((Entity<?>)entity).preAttach(id);
}
} }
@Override @Override
public void postAttach(E entity, String id) public void postAttach(E entity, String id)
{ {
if (entity instanceof Entity) entity.postAttach(id);
{
((Entity<?>)entity).postAttach(id);
}
} }
@Override @Override
public void preDetach(E entity, String id) public void preDetach(E entity, String id)
{ {
if (entity instanceof Entity) entity.preDetach(id);
{
((Entity<?>)entity).preDetach(id);
}
} }
@Override @Override
public void postDetach(E entity, String id) public void postDetach(E entity, String id)
{ {
if (entity instanceof Entity) entity.postDetach(id);
{
((Entity<?>)entity).postDetach(id);
}
} }
// -------------------------------------------- // // -------------------------------------------- //
@ -450,28 +402,6 @@ public class Coll<E> extends CollAbstract<E>
// SYNCLOG // SYNCLOG
// -------------------------------------------- // // -------------------------------------------- //
// The strings are the ids.
protected Map<String, EntityMeta> metaData;
protected EntityMeta getMetaFixed(String id)
{
if (id == null) throw new NullPointerException("id");
EntityMeta meta = this.metaData.get(id);
if (meta == null)
{
meta = new EntityMeta();
this.metaData.put(id, meta);
}
return meta;
}
protected EntityMeta setMetaFixed(String id, EntityMeta meta)
{
if (id == null) throw new NullPointerException("id");
if (meta == null) return this.metaData.remove(id);
else return this.metaData.put(id, meta);
}
// Log database synchronization for display in the "/massivecore mstore stats" command. // Log database synchronization for display in the "/massivecore mstore stats" command.
private Map<String, Long> id2out = new TreeMap<String, Long>(); private Map<String, Long> id2out = new TreeMap<String, Long>();
private Map<String, Long> id2in = new TreeMap<String, Long>(); private Map<String, Long> id2in = new TreeMap<String, Long>();
@ -502,26 +432,22 @@ public class Coll<E> extends CollAbstract<E>
// SYNC LOWLEVEL IO ACTIONS // SYNC LOWLEVEL IO ACTIONS
// -------------------------------------------- // // -------------------------------------------- //
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override @Override
public synchronized E removeAtLocalFixed(String id) public synchronized E removeAtLocalFixed(String id)
{ {
if (id == null) throw new NullPointerException("id"); if (id == null) throw new NullPointerException("id");
this.removeIdentifiedModificationFixed(id); this.removeIdentifiedModificationFixed(id);
this.setMetaFixed(id, null);
E entity = this.id2entity.remove(id); E entity = this.id2entity.remove(id);
if (entity == null) return null; if (entity == null) return null;
entity.clearSyncLogFields();
this.entity2id.remove(entity); this.entity2id.remove(entity);
// Remove entity reference info // Remove entity reference info
if (entity instanceof Entity) entity.setColl(null);
{ entity.setId(null);
((Entity)entity).setColl(null);
((Entity)entity).setId(null);
}
return entity; return entity;
} }
@ -532,9 +458,9 @@ public class Coll<E> extends CollAbstract<E>
if (id == null) throw new NullPointerException("id"); if (id == null) throw new NullPointerException("id");
this.removeIdentifiedModificationFixed(id); this.removeIdentifiedModificationFixed(id);
this.setMetaFixed(id, null);
this.getDb().delete(this, id); this.getDb().delete(this, id);
Mixin.syncModification(this, id);
} }
@Override @Override
@ -543,20 +469,18 @@ public class Coll<E> extends CollAbstract<E>
if (id == null) throw new NullPointerException("id"); if (id == null) throw new NullPointerException("id");
this.removeIdentifiedModificationFixed(id); this.removeIdentifiedModificationFixed(id);
this.setMetaFixed(id, null);
E entity = this.id2entity.get(id); E entity = this.id2entity.get(id);
if (entity == null) return; if (entity == null) return;
entity.clearSyncLogFields();
EntityMeta meta = this.getMetaFixed(id);
JsonElement raw = this.getGson().toJsonTree(entity, this.getEntityClass()); JsonElement raw = this.getGson().toJsonTree(entity, this.getEntityClass());
meta.setLastRaw(raw); entity.setLastRaw(raw);
if (this.isDefault(entity)) if (this.isDefault(entity))
{ {
this.getDb().delete(this, id); this.getDb().delete(this, id);
meta.setDefault(true); entity.setLastDefault(true);
} }
else else
{ {
@ -564,8 +488,9 @@ public class Coll<E> extends CollAbstract<E>
// TODO: This fail should not happen often. We could handle it better though. // TODO: This fail should not happen often. We could handle it better though.
// Perhaps we should log it, or simply try again. // Perhaps we should log it, or simply try again.
if (mtime == 0) return; if (mtime == 0) return;
meta.setMtime(mtime); entity.setLastMtime(mtime);
} }
Mixin.syncModification(entity);
} }
@Override @Override
@ -612,11 +537,9 @@ public class Coll<E> extends CollAbstract<E>
this.attach(entity, id, false); this.attach(entity, id, false);
} }
EntityMeta meta = this.getMetaFixed(id); entity.setLastRaw(raw);
entity.setLastMtime(mtime);
meta.setLastRaw(raw); entity.setLastDefault(false);
meta.setMtime(mtime);
meta.setDefault(false);
} }
public boolean remoteEntryIsOk(String id, Entry<JsonElement, Long> remoteEntry) public boolean remoteEntryIsOk(String id, Entry<JsonElement, Long> remoteEntry)
@ -667,7 +590,6 @@ public class Coll<E> extends CollAbstract<E>
if (id == null) throw new NullPointerException("id"); if (id == null) throw new NullPointerException("id");
// Meta might be non-existing. But then we create it here. // Meta might be non-existing. But then we create it here.
// If it is examined then it will be attached anyways. // If it is examined then it will be attached anyways.
EntityMeta meta = this.getMetaFixed(id);
Modification current = this.identifiedModifications.get(id); Modification current = this.identifiedModifications.get(id);
// DEBUG // DEBUG
// if (Bukkit.isPrimaryThread()) // if (Bukkit.isPrimaryThread())
@ -692,7 +614,7 @@ public class Coll<E> extends CollAbstract<E>
// If we have it both locally and remotely. // If we have it both locally and remotely.
if (existsLocal && existsRemote) if (existsLocal && existsRemote)
{ {
long lastMtime = meta.getMtime(); long lastMtime = localEntity.getLastMtime();
// If mtime is not equal remote takes priority, and we assume it is altered. // If mtime is not equal remote takes priority, and we assume it is altered.
if ( ! remoteMtime.equals(lastMtime)) return Modification.REMOTE_ALTER; if ( ! remoteMtime.equals(lastMtime)) return Modification.REMOTE_ALTER;
@ -704,7 +626,7 @@ public class Coll<E> extends CollAbstract<E>
else if (existsLocal) else if (existsLocal)
{ {
// ...and it was default and thus not saved to the db... // ...and it was default and thus not saved to the db...
if (meta.isDefault()) if (localEntity.getLastDefault())
{ {
// ...and also actually altered. // ...and also actually altered.
// Then it is a local alter. // Then it is a local alter.
@ -756,7 +678,6 @@ public class Coll<E> extends CollAbstract<E>
// Because they are performed by calling a method on this coll. // Because they are performed by calling a method on this coll.
// Meta might be non-existing. But then we create it here. // Meta might be non-existing. But then we create it here.
// If it is examined then it will be attached anyways. // If it is examined then it will be attached anyways.
EntityMeta meta = this.getMetaFixed(id);
Modification current = this.identifiedModifications.get(id); Modification current = this.identifiedModifications.get(id);
if (current != null && current.hasTopPriority()) return current; if (current != null && current.hasTopPriority()) return current;
@ -773,14 +694,12 @@ public class Coll<E> extends CollAbstract<E>
// So we don't have this anywhere? // So we don't have this anywhere?
if ( ! existsLocal && ! existsRemote) return Modification.UNKNOWN; if ( ! existsLocal && ! existsRemote) return Modification.UNKNOWN;
Long lastMtime = meta.getMtime();
// If time is different // If time is different
// then it is remotely altered // then it is remotely altered
if (existsLocal && existsRemote && ! lastMtime.equals(remoteMtime)) return Modification.REMOTE_ALTER; if (existsLocal && existsRemote && ! remoteMtime.equals(localEntity.getLastMtime())) return Modification.REMOTE_ALTER;
// If it doesn't exist remotely, and it wasn't because it was default. It was detached remotely. // If it doesn't exist remotely, and it wasn't because it was default. It was detached remotely.
if (!existsRemote && ! meta.isDefault()) return Modification.REMOTE_DETACH; if (!existsRemote && existsLocal && ! localEntity.getLastDefault()) return Modification.REMOTE_DETACH;
// If it doesn't exist locally, it was attached remotely. // If it doesn't exist locally, it was attached remotely.
if (!existsLocal) return Modification.REMOTE_ATTACH; if (!existsLocal) return Modification.REMOTE_ATTACH;
@ -792,7 +711,7 @@ public class Coll<E> extends CollAbstract<E>
protected boolean examineHasLocalAlterFixed(String id, E entity) protected boolean examineHasLocalAlterFixed(String id, E entity)
{ {
JsonElement lastRaw = this.getMetaFixed(id).getLastRaw(); JsonElement lastRaw = entity.getLastRaw();
JsonElement currentRaw = null; JsonElement currentRaw = null;
try try
@ -1026,7 +945,6 @@ public class Coll<E> extends CollAbstract<E>
// CONSTRUCT // CONSTRUCT
// -------------------------------------------- // // -------------------------------------------- //
@SuppressWarnings("unchecked")
public Coll(String name, Class<E> entityClass, Db db, Plugin plugin, boolean creative, boolean lowercasing, boolean sorted) public Coll(String name, Class<E> entityClass, Db db, Plugin plugin, boolean creative, boolean lowercasing, boolean sorted)
{ {
// Setup the name and the parsed parts // Setup the name and the parsed parts
@ -1057,7 +975,6 @@ public class Coll<E> extends CollAbstract<E>
this.entity2id = (Entity.class.isAssignableFrom(entityClass) && sorted) ? new ConcurrentSkipListMap<E, String>((Comparator<? super E>) ComparatorEntityId.get()) : new ConcurrentHashMap<E, String>(); 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.metaData = new ConcurrentHashMap<String, EntityMeta>();
this.identifiedModifications = new ConcurrentHashMap<String, Modification>(); this.identifiedModifications = new ConcurrentHashMap<String, Modification>();
this.tickTask = new Runnable() this.tickTask = new Runnable()

View File

@ -10,7 +10,7 @@ import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonElement;
public abstract class CollAbstract<E> implements CollInterface<E> public abstract class CollAbstract<E extends Entity<E>> implements CollInterface<E>
{ {
// -------------------------------------------- // // -------------------------------------------- //
// WHAT DO WE HANDLE? // WHAT DO WE HANDLE?

View File

@ -12,7 +12,7 @@ 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.JsonElement;
public interface CollInterface<E> extends Named public interface CollInterface<E extends Entity<E>> extends Named
{ {
// -------------------------------------------- // // -------------------------------------------- //
// WHAT DO WE HANDLE? // WHAT DO WE HANDLE?
@ -93,8 +93,8 @@ public interface CollInterface<E> extends Named
public boolean isLowercasing(); public boolean isLowercasing();
public void setLowercasing(boolean lowercasing); public void setLowercasing(boolean lowercasing);
public int getLocalPollFrequency(); public int getLocalPollInfrequency();
public void setLocalPollFrequency(int frequency); public void setLocalPollInfrequency(int frequency);
public boolean isWarningOnLocalAlter(); public boolean isWarningOnLocalAlter();
public void setWarnOnLocalAlter(boolean warnOnLocalAlter); public void setWarnOnLocalAlter(boolean warnOnLocalAlter);
@ -107,7 +107,7 @@ public interface CollInterface<E> extends Named
// COPY AND CREATE // COPY AND CREATE
// -------------------------------------------- // // -------------------------------------------- //
public void copy(Object fromo, Object too); public void copy(E fromo, E too);
// This simply creates and returns a new instance // This simply creates and returns a new instance
// It does not detach/attach or anything. Just creates a new instance. // It does not detach/attach or anything. Just creates a new instance.

View File

@ -9,7 +9,7 @@ import com.massivecraft.massivecore.Aspect;
import com.massivecraft.massivecore.Multiverse; import com.massivecraft.massivecore.Multiverse;
import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.MUtil;
public abstract class Colls<C extends Coll<E>, E> public abstract class Colls<C extends Coll<E>, E extends Entity<E>>
{ {
protected Map<String, C> name2coll = new HashMap<String, C>(); protected Map<String, C> name2coll = new HashMap<String, C>();

View File

@ -3,6 +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;
/** /**
* 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
@ -12,10 +13,10 @@ import com.massivecraft.massivecore.xlib.gson.Gson;
// Self referencing generic. // Self referencing generic.
// http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206 // http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206
public abstract class Entity<E extends Entity<E>> public class Entity<E extends Entity<E>>
{ {
// -------------------------------------------- // // -------------------------------------------- //
// COLL & ID // FIELDS
// -------------------------------------------- // // -------------------------------------------- //
protected transient Coll<E> coll; protected transient Coll<E> coll;
@ -34,6 +35,25 @@ public abstract class Entity<E extends Entity<E>>
return coll.getUniverse(); return coll.getUniverse();
} }
private volatile transient JsonElement lastRaw = null;
public JsonElement getLastRaw() { return this.lastRaw; }
public void setLastRaw(JsonElement lastRaw) { this.lastRaw = lastRaw; }
private volatile transient long lastMtime = 0;
public long getLastMtime() { return this.lastMtime; }
public void setLastMtime(long lastMtime) { this.lastMtime = lastMtime; }
private volatile transient boolean lastDefault = false;
public boolean getLastDefault() { return this.lastDefault; }
public void setLastDefault(boolean lastDefault) { this.lastDefault = lastDefault; }
public void clearSyncLogFields()
{
this.lastRaw = null;
this.lastMtime = 0;
this.lastDefault = false;
}
// -------------------------------------------- // // -------------------------------------------- //
// ATTACH AND DETACH // ATTACH AND DETACH
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -1,32 +0,0 @@
package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
//TODO: Merge with entity
public class EntityMeta
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
public static final JsonElement DEFAULT_LAST_RAW = null;
public static final long DEFAULT_MTIME = 0;
public static final boolean DEFAULT_DEFAULT = false;
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private volatile JsonElement lastRaw = DEFAULT_LAST_RAW;
public JsonElement getLastRaw() { return this.lastRaw; }
public void setLastRaw(JsonElement lastRaw) { this.lastRaw = lastRaw; }
private volatile long mtime = DEFAULT_MTIME;
public long getMtime() { return this.mtime; }
public void setMtime(long mtime) { this.mtime = mtime; }
private volatile boolean isDefault = DEFAULT_DEFAULT;
public boolean isDefault() { return this.isDefault; }
public void setDefault(boolean isDefault) { this.isDefault = isDefault; }
}

View File

@ -9,6 +9,8 @@ import java.util.UUID;
import com.massivecraft.massivecore.ConfServer; import com.massivecraft.massivecore.ConfServer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.massivecraft.massivecore.xlib.gson.JsonElement;
// This class also serves the purpose of containing
// database related constants.
public class MStore public class MStore
{ {
// -------------------------------------------- // // -------------------------------------------- //
@ -16,6 +18,7 @@ public class MStore
// -------------------------------------------- // // -------------------------------------------- //
public static boolean DEBUG_ENABLED = false; public static boolean DEBUG_ENABLED = false;
public static final int DEFAULT_LOCAL_POLL_INFREQUENCY = 10;
// -------------------------------------------- // // -------------------------------------------- //
// DRIVER REGISTRY // DRIVER REGISTRY

View File

@ -56,14 +56,9 @@ public abstract class ModificationPollerAbstract extends Thread
public void identify() throws InterruptedException public void identify() throws InterruptedException
{ {
final long waitEfterColl = this.getMillisBetweenPollColl();
for (Coll<?> coll : Coll.getInstances()) for (Coll<?> coll : Coll.getInstances())
{ {
if (this.poll(coll, this.iterationCount)) this.poll(coll, this.iterationCount);
{
Thread.sleep(waitEfterColl);
}
} }
} }
@ -72,6 +67,5 @@ public abstract class ModificationPollerAbstract extends Thread
// -------------------------------------------- // // -------------------------------------------- //
public abstract long getMillisBetweenPoll(); public abstract long getMillisBetweenPoll();
public abstract long getMillisBetweenPollColl();
public abstract boolean poll(Coll<?> coll, long iterationCount); public abstract boolean poll(Coll<?> coll, long iterationCount);
} }

View File

@ -2,6 +2,9 @@ package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.MassiveCoreMConf; import com.massivecraft.massivecore.MassiveCoreMConf;
/*
* This class polls for local changes in all colls.
*/
public class ModificationPollerLocal extends ModificationPollerAbstract public class ModificationPollerLocal extends ModificationPollerAbstract
{ {
// -------------------------------------------- // // -------------------------------------------- //
@ -22,19 +25,15 @@ public class ModificationPollerLocal extends ModificationPollerAbstract
@Override @Override
public long getMillisBetweenPoll() public long getMillisBetweenPoll()
{ {
return MassiveCoreMConf.get().millisBetweenLocalPoll; // The user specifies how often a default coll should be polled.
} // Some colls might be polled more or less frequently.
return MassiveCoreMConf.get().millisBetweenLocalPoll / MStore.DEFAULT_LOCAL_POLL_INFREQUENCY;
@Override
public long getMillisBetweenPollColl()
{
return MassiveCoreMConf.get().millisBetweenLocalPollColl;
} }
@Override @Override
public boolean poll(Coll<?> coll, long iterationCount) public boolean poll(Coll<?> coll, long iterationCount)
{ {
if (iterationCount % coll.getLocalPollFrequency() == 0) if (iterationCount % coll.getLocalPollInfrequency() == 0)
{ {
coll.identifyLocalModifications(false); coll.identifyLocalModifications(false);
return true; return true;

View File

@ -2,6 +2,9 @@ package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.MassiveCoreMConf; import com.massivecraft.massivecore.MassiveCoreMConf;
/*
* This class polls for remote changes in colls.
*/
public class ModificationPollerRemote extends ModificationPollerAbstract public class ModificationPollerRemote extends ModificationPollerAbstract
{ {
// -------------------------------------------- // // -------------------------------------------- //
@ -23,13 +26,16 @@ public class ModificationPollerRemote extends ModificationPollerAbstract
@Override @Override
public long getMillisBetweenPoll() public long getMillisBetweenPoll()
{ {
return MassiveCoreMConf.get().millisBetweenRemotePoll; // We will use the default DB for this check
} if (MStore.getDb().supportsPusher())
{
return MassiveCoreMConf.get().millisBetweenRemotePollWithPusher;
}
else
{
return MassiveCoreMConf.get().millisBetweenRemotePollWithoutPusher;
}
@Override
public long getMillisBetweenPollColl()
{
return MassiveCoreMConf.get().millisBetweenRemotePollColl;
} }
@Override @Override

View File

@ -21,6 +21,10 @@ import java.util.Set;
import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.MassiveCore;
/*
* This pusher looks for changes in a flatfile database system.
* Hopefully it is quicker than the poller.
*/
public class PusherCollFlatfile extends Thread implements PusherColl public class PusherCollFlatfile extends Thread implements PusherColl
{ {
// -------------------------------------------- // // -------------------------------------------- //