Minimalizing and simplifying MStore. Also adding default sorting to entities and collections.

This commit is contained in:
Olof Larsson 2013-01-09 09:41:14 +01:00
parent 9a66c7ce2c
commit 514162387f
15 changed files with 84 additions and 85 deletions

View File

@ -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)
{

View File

@ -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);
// -------------------------------------------- //

View File

@ -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>();

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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)));
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -17,9 +17,9 @@ public class MStore
drivers.put(driver.getName(), driver);
return true;
}
public static Driver<?> getDriver(String id)
{
return drivers.get(id);
}

View File

@ -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();

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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);
}