From 1e814b1df1670f0a19a77d55848fe6f836fa4e6b Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Mon, 4 Sep 2006 23:02:22 +0000 Subject: OrderingScore supports automatic ordering direction when unspecified. --- .../com/amazon/carbonado/info/OrderedProperty.java | 20 +++++------ .../com/amazon/carbonado/qe/OrderingScore.java | 38 ++++++++++++++------ .../com/amazon/carbonado/qe/TestOrderingScore.java | 42 ++++++++++++++++++++++ 3 files changed, 77 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/amazon/carbonado/info/OrderedProperty.java b/src/main/java/com/amazon/carbonado/info/OrderedProperty.java index 7de07c0..fe53c60 100644 --- a/src/main/java/com/amazon/carbonado/info/OrderedProperty.java +++ b/src/main/java/com/amazon/carbonado/info/OrderedProperty.java @@ -56,8 +56,8 @@ public class OrderedProperty implements Appender { /** * Parses an ordering property, which may start with a '+' or '-' to - * indicate direction. If ordering prefix not specified, default direction - * is ascending. + * indicate direction. Prefix of '~' indicates unspecified direction. If + * ordering prefix not specified, default direction is ascending. * * @param info Info for Storable type containing property * @param str string to parse @@ -73,7 +73,7 @@ public class OrderedProperty implements Appender { /** * Parses an ordering property, which may start with a '+' or '-' to - * indicate direction. + * indicate direction. Prefix of '~' indicates unspecified direction. * * @param info Info for Storable type containing property * @param str string to parse @@ -98,6 +98,9 @@ public class OrderedProperty implements Appender { } else if (str.charAt(0) == '-') { direction = Direction.DESCENDING; str = str.substring(1); + } else if (str.charAt(0) == '~') { + direction = Direction.UNSPECIFIED; + str = str.substring(1); } } if (direction == null) { @@ -158,9 +161,6 @@ public class OrderedProperty implements Appender { */ @Override public String toString() { - if (mDirection == Direction.UNSPECIFIED) { - return mProperty.toString(); - } StringBuilder buf = new StringBuilder(); buf.append(mDirection.toCharacter()); try { @@ -172,11 +172,7 @@ public class OrderedProperty implements Appender { } public void appendTo(Appendable app) throws IOException { - if (mDirection == Direction.UNSPECIFIED) { - mProperty.appendTo(app); - } else { - app.append(mDirection.toCharacter()); - mProperty.appendTo(app); - } + app.append(mDirection.toCharacter()); + mProperty.appendTo(app); } } diff --git a/src/main/java/com/amazon/carbonado/qe/OrderingScore.java b/src/main/java/com/amazon/carbonado/qe/OrderingScore.java index ed52cfc..ce85cb6 100644 --- a/src/main/java/com/amazon/carbonado/qe/OrderingScore.java +++ b/src/main/java/com/amazon/carbonado/qe/OrderingScore.java @@ -177,18 +177,32 @@ public class OrderingScore { ChainedProperty indexChained = indexProp.getChainedProperty(); if (chained.equals(indexChained)) { - if (property.getDirection() != UNSPECIFIED) { - Direction indexDir = indexProp.getDirection(); - if (indexDir == UNSPECIFIED) { - indexDir = ASCENDING; - } + Direction indexDir = indexProp.getDirection(); + if (indexDir == UNSPECIFIED) { + // Assume index natural order is ascending. + indexDir = ASCENDING; + } + + if (shouldReverseOrder != null && shouldReverseOrder) { + indexDir = indexDir.reverse(); + } - if (shouldReverseOrder == null) { - shouldReverseOrder = indexDir != property.getDirection(); - } else if ((indexDir != property.getDirection()) ^ shouldReverseOrder) { - // Direction mismatch, so cannot be handled. - break indexPosMatch; + if (property.getDirection() == UNSPECIFIED) { + // Set handled property direction to match index. + property = property.direction(indexDir); + } else if (shouldReverseOrder == null) { + shouldReverseOrder = indexDir != property.getDirection(); + // Any properies already in the list had been + // originally unspecified. They might need to be + // reversed now. + if (shouldReverseOrder) { + for (int hpi = 0; hpi < handledProperties.size(); hpi++) { + handledProperties.set(hpi, handledProperties.get(hpi).reverse()); + } } + } else if (indexDir != property.getDirection()) { + // Direction mismatch, so cannot be handled. + break indexPosMatch; } handledProperties.add(property); @@ -281,7 +295,9 @@ public class OrderingScore { /** * Returns the ordering properties that the evaluated index supports. The - * list of orderings is reduced to eliminate redundancies. + * list of orderings is reduced to eliminate redundancies. If any handled + * ordering properties originally had an unspecified direction, the correct + * direction is specified in this list. * * @return handled orderings, never null */ diff --git a/src/test/java/com/amazon/carbonado/qe/TestOrderingScore.java b/src/test/java/com/amazon/carbonado/qe/TestOrderingScore.java index 91b5676..ecacf9a 100644 --- a/src/test/java/com/amazon/carbonado/qe/TestOrderingScore.java +++ b/src/test/java/com/amazon/carbonado/qe/TestOrderingScore.java @@ -543,4 +543,46 @@ public class TestOrderingScore extends TestCase { assertEquals("+doubleProp", score.getHandledOrderings().get(1).toString()); assertEquals("+longProp", score.getRemainderOrderings().get(0).toString()); } + + public void testUnspecifiedDirection() throws Exception { + // Tests that an originally unspecified ordering direction is determined. + final StorableIndex ix; + List> ops; + OrderingScore score; + Filter filter; + + ix = makeIndex(StorableTestBasic.class, "id", "intProp", "doubleProp"); + ops = makeOrderings(StorableTestBasic.class, "~intProp", "-doubleProp"); + filter = Filter.filterFor(StorableTestBasic.class, "id = ?"); + + score = OrderingScore.evaluate(ix, filter, ops); + assertEquals(2, score.getHandledCount()); + assertEquals(0, score.getRemainderCount()); + assertEquals(true, score.shouldReverseOrder()); + + assertEquals("-intProp", score.getHandledOrderings().get(0).toString()); + assertEquals("-doubleProp", score.getHandledOrderings().get(1).toString()); + + ops = makeOrderings(StorableTestBasic.class, "~id", "intProp", "~doubleProp"); + + score = OrderingScore.evaluate(ix, null, ops); + assertEquals(3, score.getHandledCount()); + assertEquals(0, score.getRemainderCount()); + assertEquals(false, score.shouldReverseOrder()); + + assertEquals("+id", score.getHandledOrderings().get(0).toString()); + assertEquals("+intProp", score.getHandledOrderings().get(1).toString()); + assertEquals("+doubleProp", score.getHandledOrderings().get(2).toString()); + + ops = makeOrderings(StorableTestBasic.class, "~id", "-intProp", "~doubleProp"); + + score = OrderingScore.evaluate(ix, null, ops); + assertEquals(3, score.getHandledCount()); + assertEquals(0, score.getRemainderCount()); + assertEquals(true, score.shouldReverseOrder()); + + assertEquals("-id", score.getHandledOrderings().get(0).toString()); + assertEquals("-intProp", score.getHandledOrderings().get(1).toString()); + assertEquals("-doubleProp", score.getHandledOrderings().get(2).toString()); + } } -- cgit v1.2.3