Make lastRaw storage optional

This commit is contained in:
Magnus Ulf Jørgensen 2018-02-18 18:06:53 +01:00
parent c9236895a4
commit 17526c3f5f
12 changed files with 171 additions and 51 deletions

View File

@ -19,6 +19,8 @@ public class ConfServer extends SimpleConfig
// FIELDS
// -------------------------------------------- //
public static boolean localPollingEnabled = true;
public static String serverid = UUID.randomUUID().toString();
public static String dburi = "default";

View File

@ -253,7 +253,7 @@ public class MassiveCore extends MassivePlugin
// Start the examine threads
// Start AFTER initializing the MConf, because they rely on the MConf.
ModificationPollerLocal.get().start();
if (ConfServer.localPollingEnabled) ModificationPollerLocal.get().start();
ModificationPollerRemote.get().start();
// Delete Files (at once and additionally after all plugins loaded)

View File

@ -1,5 +1,6 @@
package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.ConfServer;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.MassiveCoreMConf;
import com.massivecraft.massivecore.MassivePlugin;
@ -7,6 +8,7 @@ import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.comparator.ComparatorNaturalOrder;
import com.massivecraft.massivecore.mixin.MixinModification;
import com.massivecraft.massivecore.store.migrator.MigratorUtil;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.ReflectionUtil;
import com.massivecraft.massivecore.util.Txt;
import com.massivecraft.massivecore.xlib.gson.Gson;
@ -156,6 +158,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
{
if (id == null) throw new NullPointerException("id");
if (modification == null) throw new NullPointerException("modification");
Modification old = this.identifiedModifications.get(id);
if (old != null && modification.getPriority() <= old.getPriority()) return;
this.identifiedModifications.put(id, modification);
@ -168,6 +171,13 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
this.identifiedModifications.remove(id);
}
@Override
public Modification getIdentifiedModificationFixed(String id)
{
if (id == null) throw new NullPointerException("id");
return this.identifiedModifications.get(id);
}
// -------------------------------------------- //
// SYNCLOG
// -------------------------------------------- //
@ -243,7 +253,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
entity.clearSyncLogFields();
JsonObject raw = this.getGson().toJsonTree(entity, this.getEntityClass()).getAsJsonObject();
entity.setLastRaw(raw);
if (ConfServer.localPollingEnabled) entity.setLastRaw(raw);
if (this.isDefault(entity))
{
@ -341,7 +351,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
// this.putIdentifiedModificationFixed(id, Modification.UNKNOWN);
}
entity.setLastRaw(raw);
if (ConfServer.localPollingEnabled) entity.setLastRaw(raw);
entity.setLastMtime(mtime);
entity.setLastDefault(false);
@ -429,10 +439,10 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
// ...and it was modified remotely.
if ( ! remoteMtime.equals(lastMtime)) return Modification.REMOTE_ALTER;
}
// ...and we are looking for local changes
// ...and we are looking for local changes ...
if (local)
{
// ...and it was modified locally.
// ... and it was modified locally.
if (this.examineHasLocalAlterFixed(id, localEntity)) return Modification.LOCAL_ALTER;
}
}
@ -464,6 +474,16 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
protected boolean examineHasLocalAlterFixed(String id, E entity)
{
if (!ConfServer.localPollingEnabled)
{
if (MStore.DEBUG_ENABLED)
{
this.getPlugin().log("Attempted examineHasLocalAlterFixed in " + this.getDebugName() + " for " + id);
MUtil.stackTraceDebug("examineHasLocalAlterFixed");
}
return false;
}
JsonObject lastRaw = entity.getLastRaw();
JsonObject currentRaw = null;
@ -484,27 +504,13 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
}
@Override
public Modification syncIdFixed(String id, Modification modification, Entry<JsonObject, Long> remoteEntry)
public Modification syncIdFixed(String id, final Modification suppliedModification, Entry<JsonObject, Long> remoteEntry)
{
if (id == null) throw new NullPointerException("id");
if (modification == null || modification.isUnknown())
{
Long remoteMtime = null;
if (remoteEntry != null) remoteMtime = remoteEntry.getValue();
Modification actualModification = this.examineIdFixed(id, remoteMtime, true, true);
if (MassiveCoreMConf.get().warnOnLocalAlter && modification == Modification.UNKNOWN_LOG && actualModification.isModified())
{
E entity = this.idToEntity.get(id);
if (entity != null)
{
this.logModification(entity, actualModification);
}
}
modification = actualModification;
}
if (MStore.DEBUG_ENABLED) System.out.println(this.getDebugName() + " syncronising " + modification + " on " + id);
Modification modification = getActualModification(id, suppliedModification, remoteEntry);
if (MStore.DEBUG_ENABLED) this.getPlugin().log((this.getDebugName() + " syncronising " + modification + " (" + suppliedModification + ") on " + id));
// DEBUG
// MassiveCore.get().log(Txt.parse("<a>syncId <k>Coll: <v>%s <k>Entity: <v>%s <k>Modification: <v>%s", this.getName(), id, modification));
@ -553,10 +559,66 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
return modification;
}
private Modification getActualModification(String id, Modification modification, Entry<JsonObject, Long> remoteEntry)
{
if (id == null) throw new NullPointerException("id");
if (modification != null && !modification.isUnknown())
{
return modification;
}
Long remoteMtime = null;
if (remoteEntry != null) remoteMtime = remoteEntry.getValue();
// We look only remotely for changes, because local ones should be caught by .changed()
// or by the poller. This way we are certain, that all local changes where .changed() is not called
// they are found by the poller and then reported appropriately.
Modification actualModification = this.examineIdFixed(id, remoteMtime, false, true);
if (actualModification == Modification.NONE && (modification == Modification.UNKNOWN_CHANGED || modification == Modification.UNKNOWN_LOG))
{
actualModification = Modification.LOCAL_ALTER;
checkActuallyModifiedFixed(id);
}
if (MassiveCoreMConf.get().warnOnLocalAlter && modification == Modification.UNKNOWN_LOG && actualModification.isModified())
{
E entity = this.idToEntity.get(id);
if (entity != null)
{
this.logModification(entity, actualModification);
}
}
return actualModification;
}
private void checkActuallyModifiedFixed(String id)
{
if (!ConfServer.localPollingEnabled || !MassiveCoreMConf.get().warnOnLocalAlter) return;
E entity = this.getFixed(id);
boolean modified = this.examineHasLocalAlterFixed(id, entity);
if (modified) return;
List<String> messages = new MassiveList<>();
messages.add(Txt.parse("<pink>%s", this.getDebugName()));
messages.add(Txt.parse("<aqua>%s", entity.getId()));
String change = Txt.implode(messages, Txt.parse("<silver> | "));
String message = Txt.parse("<b>[No Modification] %s", change);
this.getPlugin().log(message);
}
protected void logModification(E entity, Modification modification)
{
JsonObject lastRaw = entity.getLastRaw();
if (!ConfServer.localPollingEnabled)
{
if (MStore.DEBUG_ENABLED) this.getPlugin().log("Attempted logModification in " + this.getDebugName() + " for " + entity.getId());
return;
}
if (lastRaw == null)
{
List<String> messages = new MassiveList<>();
@ -603,7 +665,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
String change = Txt.implode(changes, Txt.parse("<silver> | "));
String message = Txt.parse("<b>[Unreported Modification] %s", change);
MassiveCore.get().log(message);
this.getPlugin().log(message);
}
@Override
@ -694,7 +756,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
{
if (modification.isModified())
{
if (MStore.DEBUG_ENABLED) System.out.println(this.getDebugName() + " identified " + modification + " on " + id);
if (MStore.DEBUG_ENABLED) this.getPlugin().log(this.getDebugName() + " identified " + modification + " on " + id);
if (veto != null && ! modification.isSafe()) modification = veto;
this.putIdentifiedModificationFixed(id, modification);
}
@ -714,7 +776,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
@Override
public void syncAll()
{
this.identifyModifications(null);
this.identifyRemoteModifications(null);
this.syncIdentified();
}
@ -891,8 +953,10 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
this.getPusher().deinit();
}
// TODO: Save outwards only? We may want to avoid loads at this stage...
this.syncAll();
// syncIdentified is probably good enough. We need not load, and when
// lastRaw is not present we can't identify local modifications anyway.
//this.syncAll();
this.syncIdentified();
name2instance.remove(this.getName());
}

View File

@ -99,7 +99,7 @@ public abstract class CollAbstract<E extends Entity<E>> extends EntityContainerA
public Modification syncIdFixed(String id)
{
if (id == null) throw new NullPointerException("id");
return this.syncIdFixed(id, null);
return this.syncIdFixed(id, this.getIdentifiedModificationFixed(id));
}
@Override
@ -109,4 +109,11 @@ public abstract class CollAbstract<E extends Entity<E>> extends EntityContainerA
return this.syncIdFixed(id, modification, null);
}
@Override
public Modification getIdentifiedModification(Object oid)
{
if (oid == null) throw new NullPointerException("oid");
return this.getIdentifiedModificationFixed(this.fixIdOrThrow(oid));
}
}

View File

@ -98,6 +98,9 @@ public interface CollInterface<E extends Entity<E>> extends Named, Active, Ident
void identifyRemoteModifications(Modification veto);
void identifyRemoteModificationFixed(String id, Long remoteMtime, Modification veto);
Modification getIdentifiedModification(Object oid);
Modification getIdentifiedModificationFixed(String id);
// Init
void initLoadAllFromRemote();

View File

@ -3,6 +3,7 @@ package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.Identified;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.store.accessor.Accessor;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.xlib.gson.Gson;
import java.lang.ref.WeakReference;
@ -96,7 +97,7 @@ public class EntityInternal<E extends EntityInternal<E>> implements Identified
//System.out.println(this.getColl().getName() + ": " +this.getId() + " was modified locally");
this.getContainer().putIdentifiedModificationFixed(this.getId(), Modification.UNKNOWN);
this.getContainer().putIdentifiedModificationFixed(this.getId(), Modification.UNKNOWN_CHANGED);
}
// -------------------------------------------- //
@ -132,6 +133,19 @@ public class EntityInternal<E extends EntityInternal<E>> implements Identified
return Objects.equals(value, standard) ? null : value;
}
public <T> T convertSet(T value, T current, T standard)
{
current = this.convertGet(current, standard);
this.changed(value, current);
return Objects.equals(value, standard) ? null : value;
}
public void changed(Object o1, Object o2)
{
if (MUtil.equalsishObject(o1, o2)) return;
changed();
}
// BOOLEAN
public boolean convertGet(Boolean value)
{

View File

@ -1,5 +1,6 @@
package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.xlib.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonNull;
@ -139,7 +140,7 @@ public class GsonEqualsChecker
if (floating)
{
// Our epsilon is pretty big in order to see float and double as the same.
return Math.abs(oneNumber.doubleValue() - twoNumber.doubleValue()) < 0.0001D;
return MUtil.equalsishNumber(oneNumber, twoNumber);
}
else
{

View File

@ -7,22 +7,26 @@ public enum Modification
// ENUM
// -------------------------------------------- //
LOCAL_ALTER (true, 4),
LOCAL_ATTACH (true, 8),
LOCAL_DETACH (true, 9),
REMOTE_ALTER (true, 5),
REMOTE_ATTACH (true, 6),
REMOTE_DETACH (true, 7),
NONE (false, 1),
UNKNOWN (false, 3),
UNKNOWN_LOG(false, 2),
LOCAL_ALTER (true, 40),
LOCAL_ATTACH (true, 80),
LOCAL_DETACH (true, 90),
REMOTE_ALTER (true, 50),
REMOTE_ATTACH (true, 60),
REMOTE_DETACH (true, 70),
NONE (false, 10),
UNKNOWN (false, 30),
UNKNOWN_LOG(false, 20),
UNKNOWN_CHANGED(false, 35),
;
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
public static final int TOP_PRIORITY = 7;
// The modifications take priority over all others.
// It is local attach and local detach, because otherwise
// the system would think it was a remote attach or remote detach.
public static final int TOP_PRIORITY = 80;
// -------------------------------------------- //
// FIELDS
@ -83,6 +87,6 @@ public enum Modification
public boolean isUnknown()
{
return this == Modification.UNKNOWN || this == Modification.UNKNOWN_LOG;
return this == Modification.UNKNOWN || this == Modification.UNKNOWN_LOG || this == Modification.UNKNOWN_CHANGED;
}
}

View File

@ -1,5 +1,7 @@
package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.ConfServer;
public abstract class ModificationPollerAbstract extends Thread
{
// -------------------------------------------- //

View File

@ -1,5 +1,6 @@
package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.ConfServer;
import com.massivecraft.massivecore.MassiveCoreMConf;
/*
@ -32,6 +33,6 @@ public class ModificationPollerLocal extends ModificationPollerAbstract
public void poll(Coll<?> coll)
{
coll.identifyLocalModifications(Modification.UNKNOWN_LOG);
}
}
}

View File

@ -126,6 +126,7 @@ public class PusherCollFlatfile extends Thread implements PusherColl
case NONE:
case UNKNOWN:
case UNKNOWN_LOG:
case UNKNOWN_CHANGED:
return;
// It was modified remotely.

View File

@ -931,7 +931,7 @@ public class MUtil
if ( ! isFinite(factor)) throw new IllegalStateException("not finite factor: " + factor);
// No Change?
if (equalsish(factor, 1)) return;
if (equalsishNumber(factor, 1)) return;
for (DamageModifier modifier : DamageModifier.values())
{
@ -1767,6 +1767,8 @@ public class MUtil
return object1.equals(object2);
}
public static boolean equals(Object... objects)
{
if (objects == null) throw new NullPointerException("objects");
@ -1792,7 +1794,17 @@ public class MUtil
public static final double EQUALSISH_EPSILON = 0.0001;
public static boolean equalsish(Number number1, Number number2)
public static boolean equalsishObject(Object o1, Object o2)
{
if (o1 instanceof Number && o2 instanceof Number)
{
return equalsishNumber((Number) o1, (Number) o2);
}
return equals(o1, o2);
}
public static boolean equalsishNumber(Number number1, Number number2)
{
if (number1 == null) return number2 == null;
if (number2 == null) return false;
@ -1800,6 +1812,15 @@ public class MUtil
return Math.abs(number1.doubleValue() - number2.doubleValue()) < EQUALSISH_EPSILON;
}
/**
* @deprecated use equalsishNumber
*/
@Deprecated
public static boolean equalsish(Number number1, Number number2)
{
return equalsishNumber(number1, number2);
}
// -------------------------------------------- //
// SORTING
// -------------------------------------------- //