/* * Copyright 2013 Gordon Burgett and individual contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xflatdb.xflat; import org.xflatdb.xflat.query.IntervalProvider; import org.jdom2.xpath.XPathExpression; import org.jdom2.xpath.XPathFactory; import org.xflatdb.xflat.query.XPathQuery; import org.xflatdb.xflat.util.XPathExpressionEqualityMatcher; /** * Represents the configuration for a sharded table. A sharded table is one which * splits its data up among several files. * @author Gordon */ public class ShardsetConfig<T> { private ShardsetConfig(){ } private ShardsetConfig(ShardsetConfig other){ this.shardPropertyClass = other.shardPropertyClass; this.shardPropertySelector = other.shardPropertySelector; this.intervalProvider = other.intervalProvider; } private Class<T> shardPropertyClass; /** * Gets the class to which the string value of the property selected by the * shard property selector must be convertible. The converted value is fed * to the Interval Provider to determine the correct shard for a data row. */ public Class<T> getShardPropertyClass(){ return shardPropertyClass; } private XPathExpression<?> shardPropertySelector; /** * Gets the XPath expression that selects a property of a row which determines * the shard where the row will be placed. */ public XPathExpression<?> getShardPropertySelector(){ return shardPropertySelector; } private IntervalProvider<T> intervalProvider; /** * Gets the interval provider used to choose which shard a row will be placed in. */ public IntervalProvider<T> getIntervalProvider(){ return intervalProvider; } private boolean isId = false; /** * Gets a flag indicating whether the shard property selector is the {@link org.xflatdb.xflat.query.XPathQuery#Id} expression. */ public boolean isShardedById(){ return this.isId; } /** * Creates a ShardsetConfig describing a table sharded by ID. The shard selector * will use the {@link XPathQuery#Id} expression. * @param <U> The generic type of the ID property; all objects in the table must have the same property. * @param idClass The class of the property selected by the xpath expression. * @param idIntervalProvider A IntervalProvider 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> byId(Class<U> idClass, IntervalProvider<U> idIntervalProvider){ if(idClass == null){ throw new IllegalArgumentException("idClass cannot be null"); } if(idIntervalProvider == null){ throw new IllegalArgumentException("idIntervalProvider cannot be null"); } ShardsetConfig<U> ret = new ShardsetConfig<>(); ret.shardPropertySelector = XPathQuery.Id; ret.shardPropertyClass = idClass; ret.intervalProvider = idIntervalProvider; ret.isId = true; return ret; } /** * Creates a ShardsetConfig with the minimum configuration necessary for static-range sharding. * The remainder can be left default or set as desired. * @param <U> The generic type of the ID property; all objects in the table must have the same property. * @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 intervalProvider A IntervalProvider 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> by(String xpathProperty, Class<U> propertyClass, IntervalProvider<U> intervalProvider){ return by(XPathFactory.instance().compile(xpathProperty), propertyClass, intervalProvider); } /** * Creates a ShardsetConfig with the minimum configuration necessary for static-range sharding. * The remainder can be left default or set as desired. * @param <U> The generic type of the ID property; all objects in the table must have the same property. * @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 intervalProvider An {@link IntervalProvider} 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> by(XPathExpression<?> xpathProperty, Class<U> propertyClass, IntervalProvider<U> intervalProvider){ if(xpathProperty == null){ throw new IllegalArgumentException("xpathProperty cannot be null"); } if(propertyClass == null){ throw new IllegalArgumentException("propertyClass cannot be null"); } if(intervalProvider == null){ throw new IllegalArgumentException("intervalProvider cannot be null"); } ShardsetConfig<U> ret = new ShardsetConfig<>(); ret.shardPropertySelector = xpathProperty; ret.shardPropertyClass = propertyClass; ret.intervalProvider = intervalProvider; if(XPathExpressionEqualityMatcher.equals(xpathProperty, XPathQuery.Id)){ ret.isId = true; } return ret; } }