diff options
Diffstat (limited to 'src/main/java')
13 files changed, 239 insertions, 197 deletions
| diff --git a/src/main/java/com/amazon/carbonado/qe/ArraySortedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/ArraySortedQueryExecutor.java index 1ca2965..85b6c2e 100644 --- a/src/main/java/com/amazon/carbonado/qe/ArraySortedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/ArraySortedQueryExecutor.java @@ -37,13 +37,13 @@ public class ArraySortedQueryExecutor<S extends Storable> extends SortedQueryExe      /**
       * @param executor executor to wrap
       * @throws IllegalArgumentException if executor is null or if remainder
 -     * orderings is empty
 +     * ordering is empty
       */
      public ArraySortedQueryExecutor(QueryExecutor<S> executor,
 -                                    List<OrderedProperty<S>> handledOrderings,
 -                                    List<OrderedProperty<S>> remainderOrderings)
 +                                    OrderingList<S> handledOrdering,
 +                                    OrderingList<S> remainderOrdering)
      {
 -        super(executor, handledOrderings, remainderOrderings);
 +        super(executor, handledOrdering, remainderOrdering);
      }
      protected SortBuffer<S> createSortBuffer() {
 diff --git a/src/main/java/com/amazon/carbonado/qe/DelegatedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/DelegatedQueryExecutor.java index 9c950e0..7b1c27b 100644 --- a/src/main/java/com/amazon/carbonado/qe/DelegatedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/DelegatedQueryExecutor.java @@ -39,48 +39,60 @@ import com.amazon.carbonado.info.OrderedProperty;   * @author Brian S O'Neill
   */
  public class DelegatedQueryExecutor<S extends Storable> implements QueryExecutor<S> {
 -    private final QueryExecutor<S> mExecutor;
 -    private final Storage<S> mStorage;
 +    private static final <T> T check(T object) {
 +        if (object == null) {
 +            throw new IllegalArgumentException();
 +        }
 +        return object;
 +    }
 +
 +    private final Filter<S> mFilter;
 +    private final OrderingList<S> mOrdering;
      private final Query<S> mQuery;
      /**
 +     * @param rootStorage root storage to query
       * @param executor executor to emulate
 -     * @param storage storage to query
       * @throws IllegalArgumentException if any parameter is null
       */
 -    public DelegatedQueryExecutor(QueryExecutor<S> executor, Storage<S> storage)
 +    public DelegatedQueryExecutor(Storage<S> rootStorage, QueryExecutor<S> executor)
          throws FetchException
      {
 -        if (executor == null || storage == null) {
 -            throw new IllegalStateException();
 -        }
 -
 -        mExecutor = executor;
 -        mStorage = storage;
 +        this(rootStorage, (executor = check(executor)).getFilter(), executor.getOrdering());
 +    }
 -        Filter<S> filter = executor.getFilter();
 +    /**
 +     * @param rootStorage root storage to query
 +     * @param filter optional query filter
 +     * @param ordering optional ordering
 +     * @throws IllegalArgumentException if rootStorage is null
 +     */
 +    public DelegatedQueryExecutor(Storage<S> rootStorage,
 +                                  Filter<S> filter, OrderingList<S> ordering)
 +        throws FetchException
 +    {
 +        check(rootStorage);
          Query<S> query;
          if (filter == null) {
 -            query = storage.query();
 +            query = rootStorage.query();
          } else {
 -            query = storage.query(filter);
 +            query = rootStorage.query(filter);
          }
 -        List<OrderedProperty<S>> ordering = executor.getOrdering();
 -        if (ordering.size() > 0) {
 -            String[] orderBy = new String[ordering.size()];
 -            for (int i=0; i<orderBy.length; i++) {
 -                orderBy[i] = ordering.get(i).toString();
 -            }
 -            query = query.orderBy(orderBy);
 +        if (ordering == null) {
 +            ordering = OrderingList.emptyList();
 +        } else if (ordering.size() > 0) {
 +            query = query.orderBy(ordering.asStringArray());
          }
 +        mFilter = filter;
 +        mOrdering = ordering;
          mQuery = query;
      }
      public Class<S> getStorableType() {
 -        return mStorage.getStorableType();
 +        return mFilter.getStorableType();
      }
      public Cursor<S> fetch(FilterValues<S> values) throws FetchException {
 @@ -92,11 +104,11 @@ public class DelegatedQueryExecutor<S extends Storable> implements QueryExecutor      }
      public Filter<S> getFilter() {
 -        return mExecutor.getFilter();
 +        return mFilter;
      }
 -    public List<OrderedProperty<S>> getOrdering() {
 -        return mExecutor.getOrdering();
 +    public OrderingList<S> getOrdering() {
 +        return mOrdering;
      }
      public boolean printNative(Appendable app, int indentLevel, FilterValues<S> values)
 diff --git a/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java b/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java index 4918f08..16a8f26 100644 --- a/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java +++ b/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java @@ -41,20 +41,20 @@ import com.amazon.carbonado.info.OrderedProperty;   * @author Brian S O'Neill
   */
  public final class EmptyQuery<S extends Storable> extends AbstractQuery<S> {
 -    private final Storage<S> mStorage;
 +    private final Storage<S> mRootStorage;
      // Properties that this query is ordered by.
      private final OrderingList<S> mOrderings;
      /**
 -     * @param storage required storage object
 +     * @param rootStorage required root storage object, used by 'or' and 'not' methods
       * @param orderings optional order-by properties
       */
 -    public EmptyQuery(Storage<S> storage, OrderingList<S> orderings) {
 -        if (storage == null) {
 +    public EmptyQuery(Storage<S> rootStorage, OrderingList<S> orderings) {
 +        if (rootStorage == null) {
              throw new IllegalArgumentException();
          }
 -        mStorage = storage;
 +        mRootStorage = rootStorage;
          if (orderings == null) {
              orderings = OrderingList.emptyList();
          }
 @@ -62,22 +62,30 @@ public final class EmptyQuery<S extends Storable> extends AbstractQuery<S> {      }
      /**
 -     * @param storage required storage object
 +     * @param rootStorage required root storage object, used by 'or' and 'not' methods
 +     * @param ordering optional order-by property
 +     */
 +    public EmptyQuery(Storage<S> rootStorage, String ordering) {
 +        this(rootStorage, OrderingList.get(rootStorage.getStorableType(), ordering));
 +    }
 +
 +    /**
 +     * @param rootStorage required root storage object, used by 'or' and 'not' methods
       * @param orderings optional order-by properties
       */
 -    public EmptyQuery(Storage<S> storage, String... orderings) {
 -        this(storage, OrderingList.get(storage.getStorableType(), orderings));
 +    public EmptyQuery(Storage<S> rootStorage, String... orderings) {
 +        this(rootStorage, OrderingList.get(rootStorage.getStorableType(), orderings));
      }
      public Class<S> getStorableType() {
 -        return mStorage.getStorableType();
 +        return mRootStorage.getStorableType();
      }
      /**
       * Always returns a {@link com.amazon.carbonado.filter.ClosedFilter ClosedFilter}.
       */
      public Filter<S> getFilter() {
 -        return Filter.getClosedFilter(mStorage.getStorableType());
 +        return Filter.getClosedFilter(getStorableType());
      }
      /**
 @@ -174,12 +182,18 @@ public final class EmptyQuery<S extends Storable> extends AbstractQuery<S> {          throw new IllegalStateException("Query is already guaranteed to fetch nothing");
      }
 +    /**
 +     * Returns a query that fetches only what's specified by the given filter.
 +     */
      public Query<S> or(Filter<S> filter) throws FetchException {
 -        return mStorage.query(filter);
 +        return mRootStorage.query(filter);
      }
 +    /**
 +     * Returns a query that fetches everything, possibly in a specified order.
 +     */
      public Query<S> not() throws FetchException {
 -        Query<S> query = mStorage.query();
 +        Query<S> query = mRootStorage.query();
          if (mOrderings.size() > 0) {
              query = query.orderBy(mOrderings.asStringArray());
          }
 @@ -187,13 +201,11 @@ public final class EmptyQuery<S extends Storable> extends AbstractQuery<S> {      }
      public Query<S> orderBy(String property) throws FetchException {
 -        // This allows property to be checked for validity.
 -        return mStorage.query().orderBy(property).not();
 +        return new EmptyQuery<S>(mRootStorage, property);
      }
      public Query<S> orderBy(String... properties) throws FetchException {
 -        // This allows properties to be checked for validity.
 -        return mStorage.query().orderBy(properties).not();
 +        return new EmptyQuery<S>(mRootStorage, properties);
      }
      /**
 @@ -239,7 +251,7 @@ public final class EmptyQuery<S extends Storable> extends AbstractQuery<S> {      public void appendTo(Appendable app) throws IOException {
          app.append("Query {type=");
 -        app.append(mStorage.getStorableType().getName());
 +        app.append(getStorableType().getName());
          app.append(", filter=");
          getFilter().appendTo(app);
 diff --git a/src/main/java/com/amazon/carbonado/qe/FilteredQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/FilteredQueryExecutor.java index d2c45aa..edf51cd 100644 --- a/src/main/java/com/amazon/carbonado/qe/FilteredQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/FilteredQueryExecutor.java @@ -73,7 +73,7 @@ public class FilteredQueryExecutor<S extends Storable> extends AbstractQueryExec          return mExecutor.getFilter().and(mFilter);
      }
 -    public List<OrderedProperty<S>> getOrdering() {
 +    public OrderingList<S> getOrdering() {
          return mExecutor.getOrdering();
      }
 diff --git a/src/main/java/com/amazon/carbonado/qe/FullScanIndexedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/FullScanIndexedQueryExecutor.java index 3ac0169..e7c6f2b 100644 --- a/src/main/java/com/amazon/carbonado/qe/FullScanIndexedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/FullScanIndexedQueryExecutor.java @@ -70,8 +70,8 @@ public abstract class FullScanIndexedQueryExecutor<S extends Storable>       * Returns the natural order of the index.
       */
      @Override
 -    public List<OrderedProperty<S>> getOrdering() {
 -        return Collections.unmodifiableList(Arrays.asList(mIndex.getOrderedProperties()));
 +    public OrderingList<S> getOrdering() {
 +        return OrderingList.get(mIndex.getOrderedProperties());
      }
      protected Cursor<S> fetch() throws FetchException {
 diff --git a/src/main/java/com/amazon/carbonado/qe/FullScanQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/FullScanQueryExecutor.java index 1e2ad16..fc29983 100644 --- a/src/main/java/com/amazon/carbonado/qe/FullScanQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/FullScanQueryExecutor.java @@ -65,8 +65,8 @@ public abstract class FullScanQueryExecutor<S extends Storable> extends Abstract      /**
       * Returns an empty list.
       */
 -    public List<OrderedProperty<S>> getOrdering() {
 -        return Collections.emptyList();
 +    public OrderingList<S> getOrdering() {
 +        return OrderingList.emptyList();
      }
      public boolean printPlan(Appendable app, int indentLevel, FilterValues<S> values)
 diff --git a/src/main/java/com/amazon/carbonado/qe/IndexedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/IndexedQueryExecutor.java index 28bd7e4..a306db1 100644 --- a/src/main/java/com/amazon/carbonado/qe/IndexedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/IndexedQueryExecutor.java @@ -173,8 +173,8 @@ public abstract class IndexedQueryExecutor<S extends Storable> extends AbstractQ          return filter;
      }
 -    public List<OrderedProperty<S>> getOrdering() {
 -        return Collections.unmodifiableList(Arrays.asList(mIndex.getOrderedProperties()));
 +    public OrderingList<S> getOrdering() {
 +        return OrderingList.get(mIndex.getOrderedProperties());
      }
      public boolean printPlan(Appendable app, int indentLevel, FilterValues<S> values)
 diff --git a/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java index ef10657..9557b31 100644 --- a/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java @@ -57,26 +57,26 @@ import com.amazon.carbonado.info.StorableIntrospector;  public class JoinedQueryExecutor<A extends Storable, B extends Storable>
      extends AbstractQueryExecutor<B>
  {
 -    private static <A extends Storable, B extends Storable> List<OrderedProperty<B>>
 +    private static <A extends Storable, B extends Storable> OrderingList<B>
          transformOrdering(Class<B> bType,
                            String bToAProperty,
                            QueryExecutor<A> aExecutor)
      {
          StorableInfo<B> bInfo = StorableIntrospector.examine(bType);
 -        List<OrderedProperty<A>> aOrdering = aExecutor.getOrdering();
 +        OrderingList<A> aOrdering = aExecutor.getOrdering();
          int size = aOrdering.size();
 -        List<OrderedProperty<B>> bOrdering = new ArrayList<OrderedProperty<B>>(size);
 +        OrderedProperty<B>[] bOrdering = new OrderedProperty[size];
          for (int i=0; i<size; i++) {
              OrderedProperty<A> aProp = aOrdering.get(i);
              String bName = bToAProperty + '.' + aProp.getChainedProperty();
              OrderedProperty<B> bProp = OrderedProperty
                  .get(ChainedProperty.parse(bInfo, bName), aProp.getDirection());
 -            bOrdering.add(bProp);
 +            bOrdering[i] = bProp;
          }
 -        return Collections.unmodifiableList(bOrdering);
 +        return OrderingList.get(bOrdering);
      }
      private final JoinedCursorFactory<A, B> mFactory;
 @@ -84,7 +84,7 @@ public class JoinedQueryExecutor<A extends Storable, B extends Storable>      private final FilterValues<A> mAFilterValues;
      private final Filter<B> mBFilter;
 -    private final List<OrderedProperty<B>> mBOrdering;
 +    private final OrderingList<B> mBOrdering;
      /**
       * @param repo access to storage instances for properties
 @@ -145,7 +145,7 @@ public class JoinedQueryExecutor<A extends Storable, B extends Storable>          return mFactory.join(mAExecutor.fetch(transferValues(values)));
      }
 -    public List<OrderedProperty<B>> getOrdering() {
 +    public OrderingList<B> getOrdering() {
          return mBOrdering;
      }
 diff --git a/src/main/java/com/amazon/carbonado/qe/KeyQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/KeyQueryExecutor.java index fe07ed6..8209be7 100644 --- a/src/main/java/com/amazon/carbonado/qe/KeyQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/KeyQueryExecutor.java @@ -78,8 +78,8 @@ public abstract class KeyQueryExecutor<S extends Storable> extends AbstractQuery      /**
       * Returns an empty list.
       */
 -    public List<OrderedProperty<S>> getOrdering() {
 -        return Collections.emptyList();
 +    public OrderingList<S> getOrdering() {
 +        return OrderingList.emptyList();
      }
      public boolean printPlan(Appendable app, int indentLevel, FilterValues<S> values)
 diff --git a/src/main/java/com/amazon/carbonado/qe/OrderingList.java b/src/main/java/com/amazon/carbonado/qe/OrderingList.java index 907453d..0cb1fc4 100644 --- a/src/main/java/com/amazon/carbonado/qe/OrderingList.java +++ b/src/main/java/com/amazon/carbonado/qe/OrderingList.java @@ -43,14 +43,14 @@ public class OrderingList<S extends Storable> extends AbstractList<OrderedProper      private static final Map<Class, OrderingList> cCache;
      static {
 -	cCache = new SoftValuedHashMap();
 +        cCache = new SoftValuedHashMap();
      }
      /**
       * Returns a canonical empty instance.
       */
      public static <S extends Storable> OrderingList<S> emptyList() {
 -	return EMPTY_LIST;
 +        return EMPTY_LIST;
      }
      /**
 @@ -59,10 +59,10 @@ public class OrderingList<S extends Storable> extends AbstractList<OrderedProper       * @throws IllegalArgumentException if ordering property is not in S
       */
      public static <S extends Storable> OrderingList<S> get(Class<S> type, String property) {
 -	if (property == null) {
 -	    return EMPTY_LIST;
 -	}
 -	return getListNode(type).nextNode(type, property);
 +        if (property == null) {
 +            return EMPTY_LIST;
 +        }
 +        return getListNode(type).nextNode(type, property);
      }
      /**
 @@ -71,14 +71,14 @@ public class OrderingList<S extends Storable> extends AbstractList<OrderedProper       * @throws IllegalArgumentException if any ordering property is not in S
       */
      public static <S extends Storable> OrderingList<S> get(Class<S> type, String... orderings) {
 -	if (orderings == null || orderings.length == 0) {
 -	    return EMPTY_LIST;
 -	}
 +        if (orderings == null || orderings.length == 0) {
 +            return EMPTY_LIST;
 +        }
 -	OrderingList<S> node = getListNode(type);
 -	for (String property : orderings) {
 -	    node = node.nextNode(type, property);
 -	}
 +        OrderingList<S> node = getListNode(type);
 +        for (String property : orderings) {
 +            node = node.nextNode(type, property);
 +        }
          return node;
      }
 @@ -87,30 +87,30 @@ public class OrderingList<S extends Storable> extends AbstractList<OrderedProper       * Returns a canonical instance composed of the given orderings.
       */
      public static <S extends Storable> OrderingList<S> get(OrderedProperty<S>... orderings) {
 -	if (orderings == null || orderings.length == 0) {
 -	    return EMPTY_LIST;
 -	}
 +        if (orderings == null || orderings.length == 0) {
 +            return EMPTY_LIST;
 +        }
 -	Class<S> type = orderings[0].getChainedProperty().getPrimeProperty().getEnclosingType();
 +        Class<S> type = orderings[0].getChainedProperty().getPrimeProperty().getEnclosingType();
 -	OrderingList<S> node = getListNode(type);
 -	for (OrderedProperty<S> property : orderings) {
 -	    node = node.nextNode(property);
 -	}
 +        OrderingList<S> node = getListNode(type);
 +        for (OrderedProperty<S> property : orderings) {
 +            node = node.nextNode(property);
 +        }
          return node;
      }
      private static <S extends Storable> OrderingList<S> getListNode(Class<S> type) {
 -	OrderingList<S> node;
 -	synchronized (cCache) {
 -	    node = (OrderingList<S>) cCache.get(type);
 -	    if (node == null) {
 -		node = new OrderingList<S>();
 -		cCache.put(type, node);
 -	    }
 -	}
 -	return node;
 +        OrderingList<S> node;
 +        synchronized (cCache) {
 +            node = (OrderingList<S>) cCache.get(type);
 +            if (node == null) {
 +                node = new OrderingList<S>();
 +                cCache.put(type, node);
 +            }
 +        }
 +        return node;
      }
      private final OrderingList<S> mParent;
 @@ -123,105 +123,129 @@ public class OrderingList<S extends Storable> extends AbstractList<OrderedProper      private String[] mOrderingStrings;
      private OrderingList() {
 -	mParent = null;
 -	mProperty = null;
 -	mSize = 0;
 +        mParent = null;
 +        mProperty = null;
 +        mSize = 0;
      }
      private OrderingList(OrderingList<S> parent, OrderedProperty<S> property) {
 -	if (property == null) {
 -	    throw new IllegalArgumentException("Ordering property is null");
 -	}
 -	mParent = parent;
 -	mProperty = property;
 -	mSize = parent.mSize + 1;
 +        if (property == null) {
 +            throw new IllegalArgumentException("Ordering property is null");
 +        }
 +        mParent = parent;
 +        mProperty = property;
 +        mSize = parent.mSize + 1;
      }
      public int size() {
 -	return mSize;
 +        return mSize;
      }
      public OrderedProperty<S> get(int index) {
 -	return asArray()[index];
 +        return asArray()[index];
 +    }
 +
 +    /**
 +     * Returns a list which concatenates this one with the other one.
 +     */
 +    public OrderingList<S> concat(OrderingList<S> other) {
 +        if (size() == 0) {
 +            return other;
 +        }
 +
 +        OrderingList<S> node = this;
 +
 +        if (other.size() > 0) {
 +            for (OrderedProperty<S> property : other) {
 +                node = node.nextNode(property);
 +            }
 +        }
 +
 +        return node;
      }
 +    /**
 +     * This method is not public because the array is not a clone.
 +     */
      private OrderedProperty<S>[] asArray() {
 -	if (mOrderings == null) {
 -	    OrderedProperty<S>[] orderings = new OrderedProperty[mSize];
 -	    OrderingList<S> node = this;
 -	    for (int i=mSize; --i>=0; ) {
 -		orderings[i] = node.mProperty;
 -		node = node.mParent;
 -	    }
 -	    mOrderings = orderings;
 -	}
 -	return mOrderings;
 +        if (mOrderings == null) {
 +            OrderedProperty<S>[] orderings = new OrderedProperty[mSize];
 +            OrderingList<S> node = this;
 +            for (int i=mSize; --i>=0; ) {
 +                orderings[i] = node.mProperty;
 +                node = node.mParent;
 +            }
 +            mOrderings = orderings;
 +        }
 +        return mOrderings;
      }
      /**
       * Returns the orderings as qualified string property names. Each is
       * prefixed with a '+' or '-'.
 +     *
 +     * <p>This method is not public because the array is not a clone.
       */
      String[] asStringArray() {
 -	if (mOrderingStrings == null) {
 -	    String[] orderings = new String[mSize];
 -	    OrderingList<S> node = this;
 -	    for (int i=mSize; --i>=0; ) {
 -		orderings[i] = node.mProperty.toString();
 -		node = node.mParent;
 -	    }
 -	    mOrderingStrings = orderings;
 -	}
 -	return mOrderingStrings;
 +        if (mOrderingStrings == null) {
 +            String[] orderings = new String[mSize];
 +            OrderingList<S> node = this;
 +            for (int i=mSize; --i>=0; ) {
 +                orderings[i] = node.mProperty.toString();
 +                node = node.mParent;
 +            }
 +            mOrderingStrings = orderings;
 +        }
 +        return mOrderingStrings;
      }
      @Override
      public int hashCode() {
 -	return System.identityHashCode(this);
 +        return System.identityHashCode(this);
      }
      @Override
      public boolean equals(Object other) {
 -	if (this == other) {
 -	    return true;
 -	}
 -	return super.equals(other);
 +        if (this == other) {
 +            return true;
 +        }
 +        return super.equals(other);
      }
      private synchronized OrderingList<S> nextNode(Class<S> type, String property) {
 -	OrderingList<S> node;
 -	if (mNextNode == null) {
 -	    mNextNode = new HashMap<Object, OrderingList<S>>();
 -	    node = null;
 -	} else {
 -	    node = mNextNode.get(property);
 -	}
 -
 -	if (node == null) {
 -	    OrderedProperty<S> op = OrderedProperty
 -		.parse(StorableIntrospector.examine(type), property);
 +        OrderingList<S> node;
 +        if (mNextNode == null) {
 +            mNextNode = new HashMap<Object, OrderingList<S>>();
 +            node = null;
 +        } else {
 +            node = mNextNode.get(property);
 +        }
 +
 +        if (node == null) {
 +            OrderedProperty<S> op = OrderedProperty
 +                .parse(StorableIntrospector.examine(type), property);
 +
 +            node = nextNode(op);
 +            mNextNode.put(property, node);
 +        }
 -	    node = nextNode(op);
 -	    mNextNode.put(property, node);
 -	}
 -
 -	return node;
 +        return node;
      }
      private synchronized OrderingList<S> nextNode(OrderedProperty<S> property) {
 -	OrderingList<S> node;
 -	if (mNextNode == null) {
 -	    mNextNode = new HashMap<Object, OrderingList<S>>();
 -	    node = null;
 -	} else {
 -	    node = mNextNode.get(property);
 -	}
 -
 -	if (node == null) {
 -	    node = new OrderingList<S>(this, property);
 -	    mNextNode.put(property, node);
 -	}
 -
 -	return node;
 +        OrderingList<S> node;
 +        if (mNextNode == null) {
 +            mNextNode = new HashMap<Object, OrderingList<S>>();
 +            node = null;
 +        } else {
 +            node = mNextNode.get(property);
 +        }
 +
 +        if (node == null) {
 +            node = new OrderingList<S>(this, property);
 +            mNextNode.put(property, node);
 +        }
 +
 +        return node;
      }
  }
 diff --git a/src/main/java/com/amazon/carbonado/qe/QueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/QueryExecutor.java index 024c31c..c81077f 100644 --- a/src/main/java/com/amazon/carbonado/qe/QueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/QueryExecutor.java @@ -65,7 +65,7 @@ public interface QueryExecutor<S extends Storable> {       *
       * @return query ordering in an unmodifiable list
       */
 -    List<OrderedProperty<S>> getOrdering();
 +    OrderingList<S> getOrdering();
      /**
       * Prints the native query to any appendable, if applicable.
 diff --git a/src/main/java/com/amazon/carbonado/qe/SortedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/SortedQueryExecutor.java index 48defa7..b5fdcb9 100644 --- a/src/main/java/com/amazon/carbonado/qe/SortedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/SortedQueryExecutor.java @@ -49,46 +49,46 @@ public abstract class SortedQueryExecutor<S extends Storable> extends AbstractQu      private final Comparator<S> mHandledComparator;
      private final Comparator<S> mFinisherComparator;
 -    private final List<OrderedProperty<S>> mHandledOrderings;
 -    private final List<OrderedProperty<S>> mRemainderOrderings;
 +    private final OrderingList<S> mHandledOrdering;
 +    private final OrderingList<S> mRemainderOrdering;
      /**
       * @param executor executor to wrap
 -     * @param handledOrderings optional handled orderings
 -     * @param remainderOrderings required remainder orderings
 +     * @param handledOrdering optional handled ordering
 +     * @param remainderOrdering required remainder ordering
       * @throws IllegalArgumentException if executor is null or if remainder
 -     * orderings is empty
 +     * ordering is empty
       */
      public SortedQueryExecutor(QueryExecutor<S> executor,
 -                               List<OrderedProperty<S>> handledOrderings,
 -                               List<OrderedProperty<S>> remainderOrderings)
 +                               OrderingList<S> handledOrdering,
 +                               OrderingList<S> remainderOrdering)
      {
          if (executor == null) {
              throw new IllegalArgumentException();
          }
          mExecutor = executor;
 -        if (handledOrderings != null && handledOrderings.size() == 0) {
 -            handledOrderings = null;
 +        if (handledOrdering != null && handledOrdering.size() == 0) {
 +            handledOrdering = null;
          }
 -        if (remainderOrderings != null && remainderOrderings.size() == 0) {
 -            remainderOrderings = null;
 +        if (remainderOrdering != null && remainderOrdering.size() == 0) {
 +            remainderOrdering = null;
          }
 -        if (remainderOrderings == null) {
 +        if (remainderOrdering == null) {
              throw new IllegalArgumentException();
          }
 -        if (handledOrderings == null) {
 +        if (handledOrdering == null) {
              mHandledComparator = null;
 -            mHandledOrderings = Collections.emptyList();
 +            mHandledOrdering = OrderingList.emptyList();
          } else {
 -            mHandledComparator = SortedCursor.createComparator(handledOrderings);
 -            mHandledOrderings = handledOrderings;
 +            mHandledComparator = SortedCursor.createComparator(handledOrdering);
 +            mHandledOrdering = handledOrdering;
          }
 -        mFinisherComparator = SortedCursor.createComparator(remainderOrderings);
 -        mRemainderOrderings = remainderOrderings;
 +        mFinisherComparator = SortedCursor.createComparator(remainderOrdering);
 +        mRemainderOrdering = remainderOrdering;
      }
      public Cursor<S> fetch(FilterValues<S> values) throws FetchException {
 @@ -106,32 +106,26 @@ public abstract class SortedQueryExecutor<S extends Storable> extends AbstractQu          return mExecutor.getFilter();
      }
 -    public List<OrderedProperty<S>> getOrdering() {
 -        if (mHandledOrderings.size() == 0) {
 -            return mRemainderOrderings;
 +    public OrderingList<S> getOrdering() {
 +        if (mHandledOrdering.size() == 0) {
 +            return mRemainderOrdering;
          }
 -        if (mRemainderOrderings.size() == 0) {
 -            return mHandledOrderings;
 +        if (mRemainderOrdering.size() == 0) {
 +            return mHandledOrdering;
          }
 -        List<OrderedProperty<S>> ordering = new ArrayList<OrderedProperty<S>>
 -            (mHandledOrderings.size() + mRemainderOrderings.size());
 -
 -        ordering.addAll(mHandledOrderings);
 -        ordering.addAll(mRemainderOrderings);
 -
 -        return ordering;
 +        return mHandledOrdering.concat(mRemainderOrdering);
      }
      public boolean printPlan(Appendable app, int indentLevel, FilterValues<S> values)
          throws IOException
      {
          indent(app, indentLevel);
 -        if (mHandledOrderings.size() == 0) {
 +        if (mHandledOrdering.size() == 0) {
              app.append("full sort: ");
          } else {
              app.append("finish sort: ");
          }
 -        app.append(mRemainderOrderings.toString());
 +        app.append(mRemainderOrdering.toString());
          newline(app);
          mExecutor.printPlan(app, increaseIndent(indentLevel), values);
          return true;
 diff --git a/src/main/java/com/amazon/carbonado/qe/UnionQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/UnionQueryExecutor.java index 39e6157..5d2a5c6 100644 --- a/src/main/java/com/amazon/carbonado/qe/UnionQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/UnionQueryExecutor.java @@ -51,7 +51,7 @@ public class UnionQueryExecutor<S extends Storable> extends AbstractQueryExecuto      }
      private final QueryExecutor<S>[] mExecutors;
 -    private final List<OrderedProperty<S>> mTotalOrderings;
 +    private final OrderingList<S> mTotalOrdering;
      private final Comparator<S> mOrderComparator;
      /**
 @@ -70,17 +70,17 @@ public class UnionQueryExecutor<S extends Storable> extends AbstractQueryExecuto          if (executors == null || executors.size() == 0) {
              throw new IllegalArgumentException();
          }
 -        List<OrderedProperty<S>> totalOrderings = executors.get(0).getOrdering();
 +        OrderingList<S> totalOrdering = executors.get(0).getOrdering();
          // Compare for consistency.
          for (int i=1; i<executors.size(); i++) {
 -            if (!totalOrderings.equals(executors.get(i).getOrdering())) {
 +            if (!totalOrdering.equals(executors.get(i).getOrdering())) {
                  throw new IllegalArgumentException("Ordering doesn't match");
              }
          }
          mExecutors = new QueryExecutor[executors.size()];
          executors.toArray(mExecutors);
 -        mTotalOrderings = totalOrderings;
 -        mOrderComparator = SortedCursor.createComparator(totalOrderings);
 +        mTotalOrdering = totalOrdering;
 +        mOrderComparator = SortedCursor.createComparator(totalOrdering);
      }
      public Cursor<S> fetch(FilterValues<S> values) throws FetchException {
 @@ -105,8 +105,8 @@ public class UnionQueryExecutor<S extends Storable> extends AbstractQueryExecuto          return filter;
      }
 -    public List<OrderedProperty<S>> getOrdering() {
 -        return mTotalOrderings;
 +    public OrderingList<S> getOrdering() {
 +        return mTotalOrdering;
      }
      public boolean printPlan(Appendable app, int indentLevel, FilterValues<S> values)
 | 
