Permalink
Browse files

RangeProvider now uses intervals instead, no sense having more than o…

…ne of those types.

Signed-off-by: gburgett <gordon.burgett@gmail.com>
  • Loading branch information...
1 parent f8c1913 commit f076ed2772f5923bfcfd3630f57f9db5f7e3681e @gburgett committed Jan 17, 2013
@@ -1,35 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.gburgett.xflat;
-
-import java.util.Comparator;
-
-/**
- *
- * @author Gordon
- */
-public interface Range<T> {
- /**
- * Determines whether the value fits within this range.
- * @param value The value to test.
- * @return true if the value fits in the range, false otherwise.
- */
- public boolean contains(T value);
-
- /**
- * Returns an integer describing whether the given value is less than,
- * greater than, or contained within the limits of the given range.
- * @param value The value to compare to this range.
- * @return 0 if (@link #contains(T ) } is true, otherwise a negative or positive
- * value indicating whether the value is less than or greater than this range.
- */
- public int compareTo(T value);
-
- /**
- * Gets a unique name for this range that will distinguish it from other ranges.
- * @return
- */
- public String getName();
-}
@@ -4,7 +4,7 @@
*/
package org.gburgett.xflat;
-import org.gburgett.xflat.range.RangeProvider;
+import org.gburgett.xflat.query.IntervalProvider;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;
@@ -22,7 +22,7 @@ private ShardsetConfig(){
private ShardsetConfig(ShardsetConfig other){
this.shardPropertyClass = other.shardPropertyClass;
this.shardPropertySelector = other.shardPropertySelector;
- this.rangeProvider = other.rangeProvider;
+ this.intervalProvider = other.intervalProvider;
}
private Class<T> shardPropertyClass;
@@ -35,9 +35,9 @@ private ShardsetConfig(ShardsetConfig other){
return shardPropertySelector;
}
- private RangeProvider<T> rangeProvider;
- public RangeProvider<T> getRangeProvider(){
- return rangeProvider;
+ private IntervalProvider<T> intervalProvider;
+ public IntervalProvider<T> getIntervalProvider(){
+ return intervalProvider;
}
@@ -48,12 +48,12 @@ private ShardsetConfig(ShardsetConfig other){
* @param <U>
* @param xpathProperty An XPath expression selecting a property of the data to shard on.
* @param propertyClass The class of the property selected by the xpath expression.
- * @param rangeProvider A RangeProvider that determines the static ranges for the
+ * @param intervalProvider A RangeProvider that determines the static ranges for the
* property, each range will have its own file.
* @return A new shardset config.
*/
- public static <U> ShardsetConfig<U> create(String xpathProperty, Class<U> propertyClass, RangeProvider<U> rangeProvider){
- return create(XPathFactory.instance().compile(xpathProperty), propertyClass, rangeProvider);
+ public static <U> ShardsetConfig<U> create(String xpathProperty, Class<U> propertyClass, IntervalProvider<U> intervalProvider){
+ return create(XPathFactory.instance().compile(xpathProperty), propertyClass, intervalProvider);
}
/**
@@ -66,11 +66,11 @@ private ShardsetConfig(ShardsetConfig other){
* property, each range will have its own file.
* @return A new shardset config.
*/
- public static <U> ShardsetConfig<U> create(XPathExpression<?> xpathProperty, Class<U> propertyClass, RangeProvider<U> rangeProvider){
+ public static <U> ShardsetConfig<U> create(XPathExpression<?> xpathProperty, Class<U> propertyClass, IntervalProvider<U> rangeProvider){
ShardsetConfig<U> ret = new ShardsetConfig<>();
ret.shardPropertySelector = xpathProperty;
ret.shardPropertyClass = propertyClass;
- ret.rangeProvider = rangeProvider;
+ ret.intervalProvider = rangeProvider;
@@ -15,23 +15,23 @@
import java.util.concurrent.TimeUnit;
import org.gburgett.xflat.Cursor;
import org.gburgett.xflat.EngineStateException;
-import org.gburgett.xflat.Range;
import org.gburgett.xflat.ShardsetConfig;
import org.gburgett.xflat.XflatException;
import org.gburgett.xflat.convert.ConversionException;
+import org.gburgett.xflat.query.Interval;
import org.jdom2.Element;
/**
*
* @author Gordon
*/
public abstract class ShardedEngineBase<T> extends EngineBase {
- protected ConcurrentMap<Range<T>, TableMetadata> openShards = new ConcurrentHashMap<>();
+ protected ConcurrentMap<Interval<T>, TableMetadata> openShards = new ConcurrentHashMap<>();
//the engines that are spinning down while this engine spins down
- private Map<Range<T>, EngineBase> spinningDownEngines = new HashMap<>();
+ private Map<Interval<T>, EngineBase> spinningDownEngines = new HashMap<>();
- private WeakHashMap<Cursor<Range<T>>, String> openTableCursors = new WeakHashMap<>();
+ private WeakHashMap<Cursor<Interval<T>>, String> openTableCursors = new WeakHashMap<>();
private final Object spinDownSyncRoot = new Object();
@@ -69,12 +69,12 @@ public ShardedEngineBase(File file, String tableName, ShardsetConfig<T> config){
}
}
- protected Range<T> getRangeForRow(Element row){
+ protected Interval<T> getRangeForRow(Element row){
Object selected = config.getShardPropertySelector().evaluateFirst(row);
- return getRange(selected);
+ return getInterval(selected);
}
- protected Range<T> getRange(Object value){
+ protected Interval<T> getInterval(Object value){
T converted;
try {
converted = this.getConversionService().convert(value, this.config.getShardPropertyClass());
@@ -83,9 +83,9 @@ public ShardedEngineBase(File file, String tableName, ShardsetConfig<T> config){
" selected non-convertible value " + value, ex);
}
- Range<T> ret;
+ Interval<T> ret;
try{
- ret = this.config.getRangeProvider().getRange(converted);
+ ret = this.config.getIntervalProvider().getInterval(converted);
}catch(java.lang.NullPointerException ex){
throw new XflatException("Data cannot be sharded: sharding expression " + config.getShardPropertySelector().getExpression() +
" selected null value which cannot be mapped to a range");
@@ -99,8 +99,8 @@ public ShardedEngineBase(File file, String tableName, ShardsetConfig<T> config){
return ret;
}
- private EngineBase getEngine(Range<T> range){
- TableMetadata metadata = openShards.get(range);
+ private EngineBase getEngine(Interval<T> interval){
+ TableMetadata metadata = openShards.get(interval);
if(metadata == null){
//definitely ensure we aren't spinning down before we start up a new engine
synchronized(spinDownSyncRoot){
@@ -111,20 +111,20 @@ private EngineBase getEngine(Range<T> range){
}
//build the new metadata element so we can use it to provide engines
- String name = range.getName();
+ String name = this.config.getIntervalProvider().getName(interval);
metadata = this.getMetadataFactory().makeTableMetadata(name, new File(directory, name + ".xml"));
- TableMetadata weWereLate = openShards.putIfAbsent(range, metadata);
+ TableMetadata weWereLate = openShards.putIfAbsent(interval, metadata);
if(weWereLate != null){
//another thread put the new metadata already
metadata = weWereLate;
}
if(state == EngineState.SpinningDown){
- EngineBase eng = spinningDownEngines.get(range);
+ EngineBase eng = spinningDownEngines.get(interval);
if(eng == null){
//we're requesting a new engine for some kind of read, get it and let the task spin it down.
eng = metadata.provideEngine();
- spinningDownEngines.put(range, eng);
+ spinningDownEngines.put(interval, eng);
return eng;
}
}
@@ -134,7 +134,7 @@ private EngineBase getEngine(Range<T> range){
return metadata.provideEngine();
}
- protected <U> U doWithEngine(Range<T> range, EngineAction<U> action){
+ protected <U> U doWithEngine(Interval<T> range, EngineAction<U> action){
EngineState state = getState();
if(state == EngineState.Uninitialized || state == EngineState.SpunDown){
@@ -214,7 +214,7 @@ protected boolean spinDown(final SpinDownEventHandler completionEventHandler) {
}
synchronized(spinDownSyncRoot){
- for(Map.Entry<Range<T>, TableMetadata> m : this.openShards.entrySet()){
+ for(Map.Entry<Interval<T>, TableMetadata> m : this.openShards.entrySet()){
EngineBase spinningDown = m.getValue().spinDown();
this.spinningDownEngines.put(m.getKey(), spinningDown);
}
@@ -228,7 +228,7 @@ public void run() {
}
synchronized(spinDownSyncRoot){
- if(spinningDownEngines.isEmpty()){
+ if(isSpunDown()){
if(state.compareAndSet(EngineState.SpinningDown, EngineState.SpunDown)){
completionEventHandler.spinDownComplete(new SpinDownEvent(ShardedEngineBase.this));
}
@@ -258,13 +258,23 @@ public void run() {
return true;
}
+
+ /**
+ * Invoked in a synchronized context to see if the sharded engine is
+ * fully spun down. Default implementation checks whether the spinning
+ * down engines have all spun down.
+ * @return
+ */
+ protected boolean isSpunDown(){
+ return spinningDownEngines.isEmpty();
+ }
@Override
protected boolean forceSpinDown() {
this.state.set(EngineState.SpunDown);
synchronized(spinDownSyncRoot){
- for(Map.Entry<Range<T>, TableMetadata> m : this.openShards.entrySet()){
+ for(Map.Entry<Interval<T>, TableMetadata> m : this.openShards.entrySet()){
EngineBase spinningDown = m.getValue().spinDown();
this.spinningDownEngines.put(m.getKey(), spinningDown);
}
@@ -24,8 +24,7 @@
* @author Gordon
*/
public class IdShardedEngine<T> extends ShardedEngineBase<T> {
-
-
+
public IdShardedEngine(File file, String tableName, ShardsetConfig<T> config){
super(file, tableName, config);
@@ -38,7 +37,7 @@ public IdShardedEngine(File file, String tableName, ShardsetConfig<T> config){
@Override
public void insertRow(final String id, final Element data) throws DuplicateKeyException {
- doWithEngine(getRange(id), new EngineAction(){
+ doWithEngine(getInterval(id), new EngineAction(){
@Override
public Object act(Engine engine) {
engine.insertRow(id, data);
@@ -49,7 +48,7 @@ public Object act(Engine engine) {
@Override
public Element readRow(final String id) {
- return doWithEngine(getRange(id), new EngineAction<Element>(){
+ return doWithEngine(getInterval(id), new EngineAction<Element>(){
@Override
public Element act(Engine engine) {
return engine.readRow(id);
@@ -64,7 +63,7 @@ public Element act(Engine engine) {
@Override
public void replaceRow(final String id, final Element data) throws KeyNotFoundException {
- doWithEngine(getRange(id), new EngineAction(){
+ doWithEngine(getInterval(id), new EngineAction(){
@Override
public Object act(Engine engine) {
engine.replaceRow(id, data);
@@ -75,7 +74,7 @@ public Object act(Engine engine) {
@Override
public boolean update(final String id, final XpathUpdate update) throws KeyNotFoundException {
- return doWithEngine(getRange(id), new EngineAction<Boolean>(){
+ return doWithEngine(getInterval(id), new EngineAction<Boolean>(){
@Override
public Boolean act(Engine engine) {
return engine.update(id, update);
@@ -90,7 +89,7 @@ public int update(XpathQuery query, XpathUpdate update) {
@Override
public boolean upsertRow(final String id, final Element data) {
- return doWithEngine(getRange(id), new EngineAction<Boolean>(){
+ return doWithEngine(getInterval(id), new EngineAction<Boolean>(){
@Override
public Boolean act(Engine engine) {
return engine.upsertRow(id, data);
@@ -100,7 +99,7 @@ public Boolean act(Engine engine) {
@Override
public void deleteRow(final String id) throws KeyNotFoundException {
- doWithEngine(getRange(id), new EngineAction(){
+ doWithEngine(getInterval(id), new EngineAction(){
@Override
public Object act(Engine engine) {
engine.deleteRow(id);
Oops, something went wrong.

0 comments on commit f076ed2

Please sign in to comment.