From de9eccde31b45162383ce674af8dc66ad9ecbeb6 Mon Sep 17 00:00:00 2001 From: shawkins Date: Fri, 8 Nov 2013 15:05:41 -0500 Subject: [PATCH] TEIID-2731 adding a stable sort option --- .../processor/relational/SortUtility.java | 15 +++++++++++++- .../processor/relational/TestSortNode.java | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/engine/src/main/java/org/teiid/query/processor/relational/SortUtility.java b/engine/src/main/java/org/teiid/query/processor/relational/SortUtility.java index 9e2c8d8fe7..62d839e01c 100644 --- a/engine/src/main/java/org/teiid/query/processor/relational/SortUtility.java +++ b/engine/src/main/java/org/teiid/query/processor/relational/SortUtility.java @@ -39,6 +39,7 @@ import org.teiid.core.TeiidComponentException; import org.teiid.core.TeiidProcessingException; import org.teiid.core.util.Assertion; +import org.teiid.core.util.PropertiesUtils; import org.teiid.language.SortSpecification.NullOrdering; import org.teiid.logging.LogConstants; import org.teiid.logging.LogManager; @@ -114,6 +115,10 @@ public String toString() { private TupleBuffer workingBuffer; private long[] attempts = new long[2]; private boolean nonBlocking; + + private static boolean STABLE_SORT = PropertiesUtils.getBooleanProperty(System.getProperties(), "org.teiid.requireStableSort", false); //$NON-NLS-1$ + + private boolean stableSort = STABLE_SORT; public SortUtility(TupleSource sourceID, List items, Mode mode, BufferManager bufferMgr, String groupName, List schema) { @@ -325,7 +330,7 @@ protected void initialSort(boolean onePass) throws TeiidComponentException, Teii } } TupleBufferTupleSource ts = workingBuffer.createIndexedTupleSource(source != null); - ts.setReverse(workingBuffer.getRowCount() > this.batchSize); + ts.setReverse((!stableSort || mode == Mode.DUP_REMOVE) && workingBuffer.getRowCount() > this.batchSize); processed+=this.workingBuffer.getRowCount(); maxRows = Math.max(1, (totalReservedBuffers/schemaSize))*batchSize; if (mode == Mode.SORT) { @@ -560,5 +565,13 @@ public void remove() { public void setNonBlocking(boolean b) { this.nonBlocking = b; } + + public void setStableSort(boolean stableSort) { + this.stableSort = stableSort; + } + + void setBatchSize(int batchSize) { + this.batchSize = batchSize; + } } diff --git a/engine/src/test/java/org/teiid/query/processor/relational/TestSortNode.java b/engine/src/test/java/org/teiid/query/processor/relational/TestSortNode.java index 892d23895a..8ff6f82368 100644 --- a/engine/src/test/java/org/teiid/query/processor/relational/TestSortNode.java +++ b/engine/src/test/java/org/teiid/query/processor/relational/TestSortNode.java @@ -384,5 +384,25 @@ private void helpTestAllSorts(int batches) throws Exception { FakeDataStore.sampleData1(dataMgr, RealMetadataFactory.example1Cached()); TestProcessor.helpProcess(plan, dataMgr, new List[]{Collections.singletonList(null)}); } + + @Test public void testStableSort() throws Exception { + ElementSymbol es1 = new ElementSymbol("e1"); //$NON-NLS-1$ + es1.setType(DataTypeManager.DefaultDataClasses.INTEGER); + BufferManager bm = BufferManagerFactory.getStandaloneBufferManager(); + TupleBuffer tsid = bm.createTupleBuffer(Arrays.asList(es1, es1), "test", TupleSourceType.PROCESSOR); //$NON-NLS-1$ + tsid.addTuple(Arrays.asList(1, 1)); + tsid.addTuple(Arrays.asList(1, 2)); + tsid.addTuple(Arrays.asList(1, 3)); + tsid.close(); + SortUtility su = new SortUtility(tsid.createIndexedTupleSource(), Arrays.asList(es1), Arrays.asList(Boolean.TRUE), Mode.SORT, bm, "test", tsid.getSchema()); //$NON-NLS-1$ + su.setBatchSize(1); + su.setStableSort(true); + TupleBuffer out = su.sort(); + TupleSource ts = out.createIndexedTupleSource(); + assertEquals(Arrays.asList(1,1), ts.nextTuple()); + assertEquals(Arrays.asList(1,2), ts.nextTuple()); + assertEquals(Arrays.asList(1,3), ts.nextTuple()); + assertNull(ts.nextTuple()); + } }