From 84a22c3b1003a29344859b8af286e37bbe4c7b21 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" <bronee@gmail.com> Date: Tue, 5 Sep 2006 01:31:18 +0000 Subject: Added support to get free and unused orderings. --- .../com/amazon/carbonado/qe/OrderingScore.java | 95 ++++++++++++++++++++-- 1 file changed, 86 insertions(+), 9 deletions(-) (limited to 'src/main/java/com') diff --git a/src/main/java/com/amazon/carbonado/qe/OrderingScore.java b/src/main/java/com/amazon/carbonado/qe/OrderingScore.java index ce85cb6..0730b4f 100644 --- a/src/main/java/com/amazon/carbonado/qe/OrderingScore.java +++ b/src/main/java/com/amazon/carbonado/qe/OrderingScore.java @@ -112,8 +112,8 @@ public class OrderingScore<S extends Storable> { // Get filter list early to detect errors. List<PropertyFilter<S>> filterList = PropertyFilterList.get(filter); - if (orderings == null || orderings.size() == 0) { - return new OrderingScore<S>(clustered, indexProperties.length, null, null, false); + if (orderings == null) { + orderings = Collections.emptyList(); } // Ordering properties which match identity filters don't affect order @@ -127,13 +127,25 @@ public class OrderingScore<S extends Storable> { } } + // Build up list of unused properties that were filtered out. + List<OrderedProperty<S>> unusedProperties = new ArrayList<OrderedProperty<S>>(); + + for (int i=0; i<indexProperties.length; i++) { + OrderedProperty<S> indexProp = indexProperties[i]; + ChainedProperty<S> indexChained = indexProp.getChainedProperty(); + + if (identityPropSet.contains(indexChained)) { + unusedProperties.add(indexProp.direction(UNSPECIFIED)); + } + } + // If index is unique and every property is matched by an identity // filter, then there won't be any handled or remainder properties. uniquelyCheck: if (unique) { for (int i=0; i<indexProperties.length; i++) { - ChainedProperty<S> indexProp = indexProperties[i].getChainedProperty(); - if (!identityPropSet.contains(indexProp)) { + ChainedProperty<S> indexChained = indexProperties[i].getChainedProperty(); + if (!identityPropSet.contains(indexChained)) { // Missed a property, so ordering is still relevent. break uniquelyCheck; } @@ -143,7 +155,9 @@ public class OrderingScore<S extends Storable> { indexProperties.length, null, // no handled properties null, // no remainder properties - false); // no need to reverse order + false, // no need to reverse order + null, // no free properties + unusedProperties); } List<OrderedProperty<S>> handledProperties = new ArrayList<OrderedProperty<S>>(); @@ -153,6 +167,7 @@ public class OrderingScore<S extends Storable> { Set<ChainedProperty<S>> seen = new HashSet<ChainedProperty<S>>(); + boolean gap = false; int indexPos = 0; calcScore: for (int i=0; i<orderings.size(); i++) { @@ -172,7 +187,7 @@ public class OrderingScore<S extends Storable> { } indexPosMatch: - while (indexPos < indexProperties.length) { + while (!gap && indexPos < indexProperties.length) { OrderedProperty<S> indexProp = indexProperties[indexPos]; ChainedProperty<S> indexChained = indexProp.getChainedProperty(); @@ -225,7 +240,33 @@ public class OrderingScore<S extends Storable> { // Property not handled and not an identity filter. remainderProperties.add(property); - indexPos = Integer.MAX_VALUE; + gap = true; + } + + // Walk through all remaining index properties and list them as free. + List<OrderedProperty<S>> freeProperties = new ArrayList<OrderedProperty<S>>(); + + while (indexPos < indexProperties.length) { + OrderedProperty<S> freeProp = indexProperties[indexPos]; + ChainedProperty<S> freeChained = freeProp.getChainedProperty(); + + // Don't list as free if already listed as unused. + if (!identityPropSet.contains(freeChained)) { + if (shouldReverseOrder == null) { + freeProp = freeProp.direction(UNSPECIFIED); + } else { + Direction freePropDir = freePropDir = freeProp.getDirection(); + if (freePropDir == UNSPECIFIED) { + freePropDir = ASCENDING; + } + if (shouldReverseOrder) { + freeProp = freeProp.direction(freePropDir.reverse()); + } + } + freeProperties.add(freeProp); + } + + indexPos++; } if (shouldReverseOrder == null) { @@ -236,7 +277,9 @@ public class OrderingScore<S extends Storable> { indexProperties.length, handledProperties, remainderProperties, - shouldReverseOrder); + shouldReverseOrder, + freeProperties, + unusedProperties); } /** @@ -257,17 +300,28 @@ public class OrderingScore<S extends Storable> { private final boolean mShouldReverseOrder; + // Free and unused orderings are not relevant for index selection, but they + // are useful for determining a total ordering that does not adversely + // affect a query plan. Combining handled, free, and unused ordering lists + // produces all the properties of the evaluated index. + private final List<OrderedProperty<S>> mFreeOrderings; + private final List<OrderedProperty<S>> mUnusedOrderings; + private OrderingScore(boolean indexClustered, int indexPropertyCount, List<OrderedProperty<S>> handledOrderings, List<OrderedProperty<S>> remainderOrderings, - boolean shouldReverseOrder) + boolean shouldReverseOrder, + List<OrderedProperty<S>> freeOrderings, + List<OrderedProperty<S>> unusedOrderings) { mIndexClustered = indexClustered; mIndexPropertyCount = indexPropertyCount; mHandledOrderings = FilteringScore.prepareList(handledOrderings); mRemainderOrderings = FilteringScore.prepareList(remainderOrderings); mShouldReverseOrder = shouldReverseOrder; + mFreeOrderings = FilteringScore.prepareList(freeOrderings); + mUnusedOrderings = FilteringScore.prepareList(unusedOrderings); } /** @@ -333,6 +387,29 @@ public class OrderingScore<S extends Storable> { return mShouldReverseOrder; } + /** + * Returns potential ordering properties that the evaluated index can + * handle, if arranged to immediately follow the handled orderings. The + * direction of any free orderings may be UNSPECIFIED, which indicates that + * specific order is not relevent. + * + * @return free orderings, never null + */ + public List<OrderedProperty<S>> getFreeOrderings() { + return mFreeOrderings; + } + + /** + * Returns unused ordering properties of the evaluated index because they + * were filtered out. The direction of each unused ordering is UNSPECIFIED + * because specific order is not relevent. + * + * @return unused orderings, never null + */ + public List<OrderedProperty<S>> getUnusedOrderings() { + return mUnusedOrderings; + } + /** * Returns true if the given score uses an index exactly the same as this * one. The only allowed differences are in the count of remainder -- cgit v1.2.3