Minimalizing and simplifying MStore. Also adding default sorting to entities and collections.
This commit is contained in:
parent
9a66c7ce2c
commit
514162387f
@ -9,6 +9,7 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import com.massivecraft.mcore5.MCore;
|
||||
@ -18,7 +19,7 @@ import com.massivecraft.mcore5.store.accessor.Accessor;
|
||||
import com.massivecraft.mcore5.store.idstrategy.IdStrategy;
|
||||
import com.massivecraft.mcore5.store.storeadapter.StoreAdapter;
|
||||
|
||||
public class Coll<E, L> implements CollInterface<E, L>
|
||||
public class Coll<E, L extends Comparable<? super L>> implements CollInterface<E, L>
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// GLOBAL REGISTRY
|
||||
@ -72,7 +73,7 @@ public class Coll<E, L> implements CollInterface<E, L>
|
||||
protected Set<L> ids = Collections.newSetFromMap(new ConcurrentHashMap<L, Boolean>());
|
||||
@Override public Collection<L> getIds() { return Collections.unmodifiableCollection(this.ids); }
|
||||
@Override public Collection<L> getIdsRemote() { return this.getDb().getDriver().getIds(this); }
|
||||
@Override public boolean containsEntity(E entity) { return this.entities.contains(entity); };
|
||||
@Override public boolean containsEntity(Object entity) { return this.entities.contains(entity); };
|
||||
@Override
|
||||
public boolean containsId(Object oid)
|
||||
{
|
||||
@ -81,8 +82,9 @@ public class Coll<E, L> implements CollInterface<E, L>
|
||||
return this.ids.contains(id);
|
||||
}
|
||||
|
||||
|
||||
protected Set<E> entities = Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>());
|
||||
// We use a ConcurrentSkipListSet here in order for the entities to keep their natural ordering
|
||||
// You may want to have your entities implement the Comparable interface
|
||||
protected Set<E> entities = new ConcurrentSkipListSet<E>();
|
||||
@Override public Collection<E> getAll() { return Collections.unmodifiableCollection(this.entities); }
|
||||
@Override public Collection<E> getAll(Predictate<E> where) { return MStoreUtil.uglySQL(this.getAll(), where, null, null, null); }
|
||||
@Override public Collection<E> getAll(Predictate<E> where, Comparator<E> orderby) { return MStoreUtil.uglySQL(this.getAll(), where, orderby, null, null); }
|
||||
@ -114,7 +116,7 @@ public class Coll<E, L> implements CollInterface<E, L>
|
||||
// Get the id for this entity.
|
||||
protected Map<E, L> entity2id = new ConcurrentHashMap<E, L>();
|
||||
@Override public Map<E, L> getEntity2id() { return Collections.unmodifiableMap(this.entity2id); }
|
||||
@Override public L getId(E entity) { return this.entity2id.get(entity); }
|
||||
@Override public L getId(Object entity) { return this.entity2id.get(entity); }
|
||||
|
||||
@Override
|
||||
public L fixId(Object oid)
|
||||
@ -228,18 +230,18 @@ public class Coll<E, L> implements CollInterface<E, L>
|
||||
if (this.ids.contains(id)) return null;
|
||||
}
|
||||
|
||||
// Attach
|
||||
this.ids.add(id);
|
||||
this.entities.add(entity);
|
||||
this.id2entity.put(id, entity);
|
||||
this.entity2id.put(entity, id);
|
||||
|
||||
// Set this as the coll if possible.
|
||||
if (entity instanceof Entity)
|
||||
{
|
||||
((Entity)entity).setColl(this);
|
||||
}
|
||||
|
||||
// Attach
|
||||
this.id2entity.put(id, entity);
|
||||
this.entity2id.put(entity, id);
|
||||
this.ids.add(id);
|
||||
this.entities.add(entity);
|
||||
|
||||
// Make note of the change
|
||||
if (noteChange)
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ import com.massivecraft.mcore5.Predictate;
|
||||
import com.massivecraft.mcore5.store.idstrategy.IdStrategy;
|
||||
import com.massivecraft.mcore5.store.storeadapter.StoreAdapter;
|
||||
|
||||
public interface CollInterface<E, L>
|
||||
public interface CollInterface<E, L extends Comparable<? super L>>
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// WHAT DO WE HANDLE?
|
||||
@ -37,7 +37,7 @@ public interface CollInterface<E, L>
|
||||
public Collection<L> getIds();
|
||||
public Collection<L> getIdsRemote();
|
||||
public boolean containsId(Object oid);
|
||||
public boolean containsEntity(E entity);
|
||||
public boolean containsEntity(Object entity);
|
||||
|
||||
public Collection<E> getAll();
|
||||
public Collection<E> getAll(Predictate<E> where);
|
||||
@ -50,7 +50,7 @@ public interface CollInterface<E, L>
|
||||
public E get(Object oid, boolean creative);
|
||||
|
||||
public Map<E, L> getEntity2id();
|
||||
public L getId(E entity);
|
||||
public L getId(Object entity);
|
||||
public L fixId(Object oid);
|
||||
|
||||
// -------------------------------------------- //
|
||||
|
@ -9,7 +9,7 @@ import com.massivecraft.mcore5.usys.Aspect;
|
||||
import com.massivecraft.mcore5.usys.Multiverse;
|
||||
import com.massivecraft.mcore5.util.MUtil;
|
||||
|
||||
public abstract class Colls<C extends Coll<E, L>, E, L>
|
||||
public abstract class Colls<C extends Coll<E, L>, E, L extends Comparable<? super L>>
|
||||
{
|
||||
protected Map<String, C> name2coll = new HashMap<String, C>();
|
||||
|
||||
|
@ -22,7 +22,7 @@ public interface Driver<R>
|
||||
|
||||
// This is some sort of database specific id strategy with built in adapter
|
||||
public boolean registerIdStrategy(IdStrategy<?, ?> idStrategy);
|
||||
public <L> IdStrategy<L, ?> getIdStrategy(String idStrategyName);
|
||||
public <L extends Comparable<? super L>> IdStrategy<L, ?> getIdStrategy(String idStrategyName);
|
||||
|
||||
// Get the default store adapter for the driver.
|
||||
public StoreAdapter getStoreAdapter();
|
||||
@ -34,25 +34,25 @@ public interface Driver<R>
|
||||
public Set<String> getCollnames(Db<?> db);
|
||||
|
||||
// Is id X in the collection?
|
||||
public <L> boolean containsId(Coll<?, L> coll, L id);
|
||||
public <L extends Comparable<? super L>> boolean containsId(Coll<?, L> coll, L id);
|
||||
|
||||
// When was X last altered?
|
||||
public <L> Long getMtime(Coll<?, L> coll, L id);
|
||||
public <L extends Comparable<? super L>> Long getMtime(Coll<?, L> coll, L id);
|
||||
|
||||
// What ids are in the collection?
|
||||
public <L> Collection<L> getIds(Coll<?, L> coll);
|
||||
public <L extends Comparable<? super L>> Collection<L> getIds(Coll<?, L> coll);
|
||||
|
||||
// Return a map of all ids with their corresponding mtimes
|
||||
public <L> Map<L, Long> getId2mtime(Coll<?, L> coll);
|
||||
public <L extends Comparable<? super L>> Map<L, Long> getId2mtime(Coll<?, L> coll);
|
||||
|
||||
// Load the raw data for X. The second part of the entry is the remote mtime at the load.
|
||||
public <L> Entry<R, Long> load(Coll<?, L> coll, L id);
|
||||
public <L extends Comparable<? super L>> Entry<R, Long> load(Coll<?, L> coll, L id);
|
||||
|
||||
// Save raw data as X
|
||||
// Return value is the new mtime (we caused the change).
|
||||
// If the mtime is null something failed.
|
||||
public <L> Long save(Coll<?, L> coll, L id, final Object rawData);
|
||||
public <L extends Comparable<? super L>> Long save(Coll<?, L> coll, L id, final Object rawData);
|
||||
|
||||
// Delete X
|
||||
public <L> void delete(Coll<?, L> coll, L id);
|
||||
public <L extends Comparable<? super L>> void delete(Coll<?, L> coll, L id);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public abstract class DriverAbstract<R> implements Driver<R>
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <L> IdStrategy<L, ?> getIdStrategy(String idStrategyName)
|
||||
public <L extends Comparable<? super L>> IdStrategy<L, ?> getIdStrategy(String idStrategyName)
|
||||
{
|
||||
IdStrategy<?, ?> idStrategy = idStrategies.get(idStrategyName);
|
||||
return (IdStrategy<L, ?>) idStrategy;
|
||||
|
@ -72,13 +72,13 @@ public class DriverGson extends DriverAbstract<JsonElement>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> boolean containsId(Coll<?, L> coll, L id)
|
||||
public <L extends Comparable<? super L>> boolean containsId(Coll<?, L> coll, L id)
|
||||
{
|
||||
return fileFromId(coll, id).isFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Long getMtime(Coll<?, L> coll, L id)
|
||||
public <L extends Comparable<? super L>> Long getMtime(Coll<?, L> coll, L id)
|
||||
{
|
||||
File file = fileFromId(coll, id);
|
||||
if ( ! file.isFile()) return null;
|
||||
@ -86,7 +86,7 @@ public class DriverGson extends DriverAbstract<JsonElement>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Collection<L> getIds(Coll<?, L> coll)
|
||||
public <L extends Comparable<? super L>> Collection<L> getIds(Coll<?, L> coll)
|
||||
{
|
||||
List<L> ret = new ArrayList<L>();
|
||||
|
||||
@ -105,7 +105,7 @@ public class DriverGson extends DriverAbstract<JsonElement>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Map<L, Long> getId2mtime(Coll<?, L> coll)
|
||||
public <L extends Comparable<? super L>> Map<L, Long> getId2mtime(Coll<?, L> coll)
|
||||
{
|
||||
Map<L, Long> ret = new HashMap<L, Long>();
|
||||
|
||||
@ -124,7 +124,7 @@ public class DriverGson extends DriverAbstract<JsonElement>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Entry<JsonElement, Long> load(Coll<?, L> coll, L id)
|
||||
public <L extends Comparable<? super L>> Entry<JsonElement, Long> load(Coll<?, L> coll, L id)
|
||||
{
|
||||
File file = fileFromId(coll, id);
|
||||
Long mtime = file.lastModified();
|
||||
@ -137,7 +137,7 @@ public class DriverGson extends DriverAbstract<JsonElement>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Long save(Coll<?, L> coll, L id, Object rawData)
|
||||
public <L extends Comparable<? super L>> Long save(Coll<?, L> coll, L id, Object rawData)
|
||||
{
|
||||
File file = fileFromId(coll, id);
|
||||
String content = coll.getMplugin().gson.toJson((JsonElement)rawData);
|
||||
@ -146,7 +146,7 @@ public class DriverGson extends DriverAbstract<JsonElement>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> void delete(Coll<?, L> coll, L id)
|
||||
public <L extends Comparable<? super L>> void delete(Coll<?, L> coll, L id)
|
||||
{
|
||||
File file = fileFromId(coll, id);
|
||||
file.delete();
|
||||
@ -168,7 +168,7 @@ public class DriverGson extends DriverAbstract<JsonElement>
|
||||
return name.substring(0, name.length()-5);
|
||||
}
|
||||
|
||||
protected static <L> File fileFromId(Coll<?, L> coll, L id)
|
||||
protected static <L extends Comparable<? super L>> File fileFromId(Coll<?, L> coll, L id)
|
||||
{
|
||||
File collDir = getCollDir(coll);
|
||||
String idString = (String)coll.getIdStrategy().localToRemote(id);
|
||||
|
@ -72,7 +72,7 @@ public class DriverMongo extends DriverAbstract<BasicDBObject>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> boolean containsId(Coll<?, L> coll, L id)
|
||||
public <L extends Comparable<? super L>> boolean containsId(Coll<?, L> coll, L id)
|
||||
{
|
||||
DBCollection dbcoll = fixColl(coll);
|
||||
DBCursor cursor = dbcoll.find(new BasicDBObject(ID_FIELD, coll.getIdStrategy().localToRemote(id)));
|
||||
@ -80,7 +80,7 @@ public class DriverMongo extends DriverAbstract<BasicDBObject>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Long getMtime(Coll<?, L> coll, L id)
|
||||
public <L extends Comparable<? super L>> Long getMtime(Coll<?, L> coll, L id)
|
||||
{
|
||||
DBCollection dbcoll = fixColl(coll);
|
||||
BasicDBObject found = (BasicDBObject)dbcoll.findOne(new BasicDBObject(ID_FIELD, coll.getIdStrategy().localToRemote(id)), dboKeysMtime);
|
||||
@ -90,7 +90,7 @@ public class DriverMongo extends DriverAbstract<BasicDBObject>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Collection<L> getIds(Coll<?, L> coll)
|
||||
public <L extends Comparable<? super L>> Collection<L> getIds(Coll<?, L> coll)
|
||||
{
|
||||
List<L> ret = null;
|
||||
|
||||
@ -116,7 +116,7 @@ public class DriverMongo extends DriverAbstract<BasicDBObject>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Map<L, Long> getId2mtime(Coll<?, L> coll)
|
||||
public <L extends Comparable<? super L>> Map<L, Long> getId2mtime(Coll<?, L> coll)
|
||||
{
|
||||
Map<L, Long> ret = null;
|
||||
|
||||
@ -145,7 +145,7 @@ public class DriverMongo extends DriverAbstract<BasicDBObject>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Entry<BasicDBObject, Long> load(Coll<?, L> coll, L id)
|
||||
public <L extends Comparable<? super L>> Entry<BasicDBObject, Long> load(Coll<?, L> coll, L id)
|
||||
{
|
||||
DBCollection dbcoll = fixColl(coll);
|
||||
BasicDBObject raw = (BasicDBObject)dbcoll.findOne(new BasicDBObject(ID_FIELD, coll.getIdStrategy().localToRemote(id)));
|
||||
@ -155,7 +155,7 @@ public class DriverMongo extends DriverAbstract<BasicDBObject>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> Long save(Coll<?, L> coll, L id, Object rawData)
|
||||
public <L extends Comparable<? super L>> Long save(Coll<?, L> coll, L id, Object rawData)
|
||||
{
|
||||
DBCollection dbcoll = fixColl(coll);
|
||||
|
||||
@ -172,7 +172,7 @@ public class DriverMongo extends DriverAbstract<BasicDBObject>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <L> void delete(Coll<?, L> coll, L id)
|
||||
public <L extends Comparable<? super L>> void delete(Coll<?, L> coll, L id)
|
||||
{
|
||||
fixColl(coll).remove(new BasicDBObject(ID_FIELD, coll.getIdStrategy().localToRemote(id)));
|
||||
}
|
||||
|
@ -12,17 +12,12 @@ import com.massivecraft.mcore5.xlib.gson.Gson;
|
||||
|
||||
// Self referencing generic using the "getThis trick".
|
||||
// http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206
|
||||
public abstract class Entity<E extends Entity<E, L>, L>
|
||||
public abstract class Entity<E extends Entity<E, L>, L extends Comparable<? super L>> implements Comparable<E>
|
||||
{
|
||||
protected transient Coll<E, L> coll;
|
||||
protected void setColl(Coll<E, L> val) { this.coll = val; }
|
||||
public Coll<E, L> getColl() { return this.coll; }
|
||||
|
||||
protected abstract E getThis();
|
||||
protected abstract Class<E> getClazz();
|
||||
|
||||
public abstract E getDefaultInstance();
|
||||
|
||||
public String getUniverse()
|
||||
{
|
||||
Coll<E, L> coll = this.getColl();
|
||||
@ -31,9 +26,10 @@ public abstract class Entity<E extends Entity<E, L>, L>
|
||||
return coll.getUniverse();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public L attach(Coll<E, L> coll)
|
||||
{
|
||||
return coll.attach(getThis());
|
||||
return coll.attach((E) this);
|
||||
}
|
||||
|
||||
public E detach()
|
||||
@ -41,7 +37,7 @@ public abstract class Entity<E extends Entity<E, L>, L>
|
||||
Coll<E, L> coll = this.getColl();
|
||||
if (coll == null) return null;
|
||||
|
||||
return coll.detach(getThis());
|
||||
return coll.detach(this);
|
||||
}
|
||||
|
||||
public boolean attached()
|
||||
@ -49,7 +45,7 @@ public abstract class Entity<E extends Entity<E, L>, L>
|
||||
Coll<E, L> coll = this.getColl();
|
||||
if (coll == null) return false;
|
||||
|
||||
return coll.getAll().contains(getThis());
|
||||
return coll.getAll().contains(this);
|
||||
}
|
||||
|
||||
public boolean detached()
|
||||
@ -61,7 +57,7 @@ public abstract class Entity<E extends Entity<E, L>, L>
|
||||
{
|
||||
Coll<E, L> coll = this.getColl();
|
||||
if (coll == null) return null;
|
||||
return coll.getId(this.getThis());
|
||||
return coll.getId(this);
|
||||
}
|
||||
|
||||
public void changed()
|
||||
@ -102,18 +98,39 @@ public abstract class Entity<E extends Entity<E, L>, L>
|
||||
Coll<E, L> coll = this.getColl();
|
||||
if (coll != null) gson = coll.getMplugin().gson;
|
||||
|
||||
return this.getClazz().getSimpleName()+gson.toJson(this, this.getClazz());
|
||||
}
|
||||
|
||||
public E loadDefaults()
|
||||
{
|
||||
Accessor.get(this.getClazz()).copy(this.getDefaultInstance(), this.getThis());
|
||||
return this.getThis();
|
||||
return this.getClass().getSimpleName()+gson.toJson(this, this.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public E load(E that)
|
||||
{
|
||||
Accessor.get(this.getClazz()).copy(that, this.getThis());
|
||||
return this.getThis();
|
||||
Accessor.get(this.getClass()).copy(that, this);
|
||||
return (E) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(E that)
|
||||
{
|
||||
if (that == null) throw new NullPointerException("You cannot compare with null");
|
||||
|
||||
if (this.equals(that)) return 0;
|
||||
|
||||
L thisId = this.getId();
|
||||
L thatId = that.getId();
|
||||
|
||||
if (thisId == null) return -1;
|
||||
if (thatId == null) return +1;
|
||||
|
||||
int ret = thisId.compareTo(thatId);
|
||||
|
||||
// The id's may be the same if these are objects from different collections
|
||||
// We avoid zero in an ugly way like this.
|
||||
// TODO: Improve by comparing collections and then databases.
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.massivecraft.mcore5.store;
|
||||
|
||||
public class ExamineThread<E, L> extends Thread
|
||||
public class ExamineThread<E, L extends Comparable<? super L>> extends Thread
|
||||
{
|
||||
protected Coll<E, L> coll;
|
||||
|
||||
|
@ -17,9 +17,9 @@ public class MStore
|
||||
drivers.put(driver.getName(), driver);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Driver<?> getDriver(String id)
|
||||
{
|
||||
|
||||
return drivers.get(id);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import com.massivecraft.mcore5.store.CollInterface;
|
||||
* Thus you will find multiple implementations with the name "ai" (auto increment).
|
||||
* There must be one implementation per driver.
|
||||
*/
|
||||
public interface IdStrategy<L, R>
|
||||
public interface IdStrategy<L extends Comparable<? super L>, R>
|
||||
{
|
||||
// The name of the strategy (such as "auto_increment")
|
||||
public String getName();
|
||||
|
@ -4,7 +4,7 @@ import java.util.Collection;
|
||||
|
||||
import com.massivecraft.mcore5.store.CollInterface;
|
||||
|
||||
public abstract class IdStrategyAbstract<L, R> implements IdStrategy<L, R>
|
||||
public abstract class IdStrategyAbstract<L extends Comparable<? super L>, R> implements IdStrategy<L, R>
|
||||
{
|
||||
public IdStrategyAbstract(String name, Class<L> localClass, Class<R> remoteClass)
|
||||
{
|
||||
|
@ -17,12 +17,6 @@ public class Aspect extends Entity<Aspect, String>
|
||||
// META
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override protected Aspect getThis() { return this; }
|
||||
|
||||
private final static transient Aspect defaultInstance = new Aspect();
|
||||
@Override public Aspect getDefaultInstance(){ return defaultInstance; }
|
||||
@Override protected Class<Aspect> getClazz() { return Aspect.class; }
|
||||
|
||||
public static Aspect get(Object oid)
|
||||
{
|
||||
return AspectColl.i.get(oid);
|
||||
|
@ -19,12 +19,6 @@ public class Multiverse extends Entity<Multiverse, String>
|
||||
// META
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override protected Multiverse getThis() { return this; }
|
||||
|
||||
private final static transient Multiverse defaultInstance = new Multiverse();
|
||||
@Override public Multiverse getDefaultInstance(){ return defaultInstance; }
|
||||
@Override protected Class<Multiverse> getClazz() { return Multiverse.class; }
|
||||
|
||||
public static Multiverse get(Object oid)
|
||||
{
|
||||
return MultiverseColl.i.get(oid);
|
||||
|
@ -231,21 +231,13 @@ public class MUtil
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LE NICE EQUALS
|
||||
// LE NICE EQUALS and compare
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static boolean equals(Object herp, Object derp)
|
||||
{
|
||||
if (herp == null && derp == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (herp == null || derp == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (herp == null && derp == null) return true;
|
||||
if (herp == null || derp == null) return false;
|
||||
return herp.equals(derp);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user