diff --git a/README.md b/README.md index 72131f6..7c50e36 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,3 @@ Run the task "test": ```shell ./gradlew test ``` - -## TimSort - -Imported from -- src/java.base/share/classes/java/util/TimSort.java -- src/java.base/share/classes/java/util/ComparableTimSort.java diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/Educational.java b/app/src/main/java/de/uni_marburg/powersort/Educational.java similarity index 92% rename from app/src/main/java/de/uni_marburg/powersort/benchmark/Educational.java rename to app/src/main/java/de/uni_marburg/powersort/Educational.java index 22c13b2..35bb456 100644 --- a/app/src/main/java/de/uni_marburg/powersort/benchmark/Educational.java +++ b/app/src/main/java/de/uni_marburg/powersort/Educational.java @@ -1,4 +1,7 @@ -package de.uni_marburg.powersort.benchmark; +package de.uni_marburg.powersort; + +import de.uni_marburg.powersort.benchmark.DummyComparable1; +import de.uni_marburg.powersort.benchmark.NaturalOrder; import java.util.Arrays; diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/DummyComparable1.java b/app/src/main/java/de/uni_marburg/powersort/benchmark/DummyComparable1.java index 7cea94b..a404bbe 100644 --- a/app/src/main/java/de/uni_marburg/powersort/benchmark/DummyComparable1.java +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/DummyComparable1.java @@ -3,7 +3,7 @@ package de.uni_marburg.powersort.benchmark; /** * A class for tiny, comparable objects. */ -record DummyComparable1(int id) implements Comparable { +public record DummyComparable1(int id) implements Comparable { @Override public int compareTo(DummyComparable1 other) { return id - other.id; diff --git a/app/src/main/java/de/uni_marburg/powersort/data/AscendingIntegers.java b/app/src/main/java/de/uni_marburg/powersort/data/AscendingIntegers.java index c660f84..8050a21 100644 --- a/app/src/main/java/de/uni_marburg/powersort/data/AscendingIntegers.java +++ b/app/src/main/java/de/uni_marburg/powersort/data/AscendingIntegers.java @@ -3,11 +3,9 @@ package de.uni_marburg.powersort.data; import de.uni_marburg.powersort.benchmark.IntegerArray; import de.uni_marburg.powersort.benchmark.LongFormatter; -import static de.uni_marburg.powersort.data.DataArraySizes.SIZE_ASC; - public class AscendingIntegers extends IntegerSupplier { - public AscendingIntegers() { - super(IntegerArray.ascending( 1, SIZE_ASC)); + public AscendingIntegers(int size) { + super(IntegerArray.ascending( 1, size)); } @Override diff --git a/app/src/main/java/de/uni_marburg/powersort/data/DataArraySizes.java b/app/src/main/java/de/uni_marburg/powersort/data/DataArraySizes.java deleted file mode 100644 index 627a63e..0000000 --- a/app/src/main/java/de/uni_marburg/powersort/data/DataArraySizes.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.uni_marburg.powersort.data; - -public interface DataArraySizes { - int SIZE_RAND = 50_000_000; - int SIZE_ASC = 50_000_000; - int SIZE_DESC = 50_000_000; -} diff --git a/app/src/main/java/de/uni_marburg/powersort/data/DataEnum.java b/app/src/main/java/de/uni_marburg/powersort/data/DataEnum.java index af0fa35..ff9de0a 100644 --- a/app/src/main/java/de/uni_marburg/powersort/data/DataEnum.java +++ b/app/src/main/java/de/uni_marburg/powersort/data/DataEnum.java @@ -4,18 +4,23 @@ public enum DataEnum { RANDOM_INTEGERS, ASCENDING_INTEGERS, DESCENDING_INTEGERS, - ASCENDING_RUNS; + ASCENDING_RUNS, + ASCENDING_RUNS_WITH_OVERLAP; public ObjectSupplier get() { // We use a seed to get the same random list every time -> Repeatable benchmarks on same input data! // final long seed = 3651660232967549736L; // System.nanoTime() ++ Math.random() final long seed = 140506881906827520L; // (long) 'P' * (long) 'O' *(long) 'W' * (long) 'E' * (long) 'R' * (long) 'S' * (long) 'O' * (long) 'R' * (long) 'T'; + int longListSize = 50_000_000; + return switch (this) { - case RANDOM_INTEGERS -> new RandomIntegers(seed); - case ASCENDING_INTEGERS -> new AscendingIntegers(); - case DESCENDING_INTEGERS -> new DescendingIntegers(); - case ASCENDING_RUNS -> AscendingRuns.newAscendingRuns(10000, 10000, -10000); + case RANDOM_INTEGERS -> new RandomIntegers(longListSize, seed); + case ASCENDING_INTEGERS -> new AscendingIntegers(longListSize); + case DESCENDING_INTEGERS -> new DescendingIntegers(longListSize); + + case ASCENDING_RUNS -> AscendingRuns.newAscendingRuns(10_000, 10_000, -10_000); + case ASCENDING_RUNS_WITH_OVERLAP -> AscendingRuns.newAscendingRuns(10_000, 10_000, -5_000); }; } } diff --git a/app/src/main/java/de/uni_marburg/powersort/data/DescendingIntegers.java b/app/src/main/java/de/uni_marburg/powersort/data/DescendingIntegers.java index 901b08b..70a8f15 100644 --- a/app/src/main/java/de/uni_marburg/powersort/data/DescendingIntegers.java +++ b/app/src/main/java/de/uni_marburg/powersort/data/DescendingIntegers.java @@ -3,11 +3,9 @@ package de.uni_marburg.powersort.data; import de.uni_marburg.powersort.benchmark.IntegerArray; import de.uni_marburg.powersort.benchmark.LongFormatter; -import static de.uni_marburg.powersort.data.DataArraySizes.SIZE_DESC; - public class DescendingIntegers extends IntegerSupplier { - public DescendingIntegers() { - super(IntegerArray.descending(SIZE_DESC, 1)); + public DescendingIntegers(int size) { + super(IntegerArray.descending(size, 1)); } @Override diff --git a/app/src/main/java/de/uni_marburg/powersort/data/RandomIntegers.java b/app/src/main/java/de/uni_marburg/powersort/data/RandomIntegers.java index 40c46f6..f7b85ee 100644 --- a/app/src/main/java/de/uni_marburg/powersort/data/RandomIntegers.java +++ b/app/src/main/java/de/uni_marburg/powersort/data/RandomIntegers.java @@ -3,11 +3,9 @@ package de.uni_marburg.powersort.data; import de.uni_marburg.powersort.benchmark.IntegerArray; import de.uni_marburg.powersort.benchmark.LongFormatter; -import static de.uni_marburg.powersort.data.DataArraySizes.SIZE_RAND; - public class RandomIntegers extends IntegerSupplier { - public RandomIntegers(final long seed) { - super(IntegerArray.random(SIZE_RAND, seed)); + public RandomIntegers(final int size, final long seed) { + super(IntegerArray.random(size, seed)); } @Override diff --git a/app/src/main/java/de/uni_marburg/powersort/sort/ComparableTimSort.java b/app/src/main/java/de/uni_marburg/powersort/sort/ComparableTimSort.java index 8396420..1d0b78b 100644 --- a/app/src/main/java/de/uni_marburg/powersort/sort/ComparableTimSort.java +++ b/app/src/main/java/de/uni_marburg/powersort/sort/ComparableTimSort.java @@ -24,6 +24,10 @@ * questions. */ +/* + * Imported from OpenJDK git repo ComparableTimSort.java + */ + package de.uni_marburg.powersort.sort; /** diff --git a/app/src/main/java/de/uni_marburg/powersort/sort/SortEnum.java b/app/src/main/java/de/uni_marburg/powersort/sort/SortEnum.java index 151fb55..f2c6bfe 100644 --- a/app/src/main/java/de/uni_marburg/powersort/sort/SortEnum.java +++ b/app/src/main/java/de/uni_marburg/powersort/sort/SortEnum.java @@ -1,17 +1,22 @@ package de.uni_marburg.powersort.sort; +import de.uni_marburg.powersort.FinnSort.FinnSort; import de.uni_marburg.powersort.benchmark.NaturalOrder; public enum SortEnum { // BUBBLE_SORT, MERGE_SORT, - TIM_SORT; + TIM_SORT, + FIN_SORT, + ASORT; public SimpleSort get() { return switch (this) { // case BUBBLE_SORT -> array -> BubbleSort.sort(array, NaturalOrder.INSTANCE); case MERGE_SORT -> array -> MergeSort.legacyMergeSort(array, NaturalOrder.INSTANCE); case TIM_SORT -> array -> TimSort.sort(array, 0, array.length, NaturalOrder.INSTANCE, null, 0, 0); + case FIN_SORT -> array -> FinnSort.sort(array, NaturalOrder.INSTANCE); + case ASORT -> array -> ASort.sort(array, NaturalOrder.INSTANCE); }; } } diff --git a/app/src/main/java/de/uni_marburg/powersort/sort/TimSort.java b/app/src/main/java/de/uni_marburg/powersort/sort/TimSort.java index 3bab3b7..0a3958f 100644 --- a/app/src/main/java/de/uni_marburg/powersort/sort/TimSort.java +++ b/app/src/main/java/de/uni_marburg/powersort/sort/TimSort.java @@ -24,6 +24,10 @@ * questions. */ +/* + * Imported from OpenJDK git repo TimSort.java + */ + package de.uni_marburg.powersort.sort; import java.util.Comparator; diff --git a/app/src/test/java/de/uni_marburg/powersort/JUnitUtil.java b/app/src/test/java/de/uni_marburg/powersort/JUnitUtil.java new file mode 100644 index 0000000..372b152 --- /dev/null +++ b/app/src/test/java/de/uni_marburg/powersort/JUnitUtil.java @@ -0,0 +1,41 @@ +package de.uni_marburg.powersort; + +import org.junit.jupiter.params.converter.SimpleArgumentConverter; + +import java.util.Arrays; + +public class JUnitUtil { + /** + * https://stackoverflow.com/a/46850299/6334421 + */ + public static class IntArrayConverter extends SimpleArgumentConverter { + @Override + protected int[] convert(Object source, Class targetType) { + if (source instanceof String s && int[].class.isAssignableFrom(targetType)) { + if (s.isEmpty()) { + return new int[0]; + } + String[] strings = s.split("\\s*\\|\\s*"); + return Arrays.stream(strings).mapToInt(Integer::valueOf).toArray(); + } else { + throw new IllegalArgumentException("Conversion from " + source.getClass() + + " to " + targetType + " not supported."); + } + } + } + public static class IntegerArrayConverter extends SimpleArgumentConverter { + @Override + protected Integer[] convert(Object source, Class targetType) { + if (source instanceof String s && Integer[].class.isAssignableFrom(targetType)) { + if (s.isEmpty()) { + return new Integer[0]; + } + String[] strings = s.split("\\s*\\|\\s*"); + return Arrays.stream(strings).map(Integer::valueOf).toArray(Integer[]::new); + } else { + throw new IllegalArgumentException("Conversion from " + source.getClass() + + " to " + targetType + " not supported."); + } + } + } +} diff --git a/app/src/test/java/de/uni_marburg/powersort/data/AscendingRunsTest.java b/app/src/test/java/de/uni_marburg/powersort/data/AscendingRunsTest.java index 69f9b15..36e78aa 100644 --- a/app/src/test/java/de/uni_marburg/powersort/data/AscendingRunsTest.java +++ b/app/src/test/java/de/uni_marburg/powersort/data/AscendingRunsTest.java @@ -1,8 +1,8 @@ package de.uni_marburg.powersort.data; +import de.uni_marburg.powersort.JUnitUtil; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.converter.ConvertWith; -import org.junit.jupiter.params.converter.SimpleArgumentConverter; import org.junit.jupiter.params.provider.CsvSource; import java.util.Arrays; @@ -10,26 +10,6 @@ import java.util.Arrays; import static org.junit.jupiter.api.Assertions.*; class AscendingRunsTest { - /** - * https://stackoverflow.com/a/46850299/6334421 - */ - private static class IntArrayConverter extends SimpleArgumentConverter { - @Override - protected Object convert(Object source, Class targetType) { - if (source instanceof String s && int[].class.isAssignableFrom(targetType)) { - if (s.isEmpty()) { - return new int[0]; - } - String[] strings = s.split("\\s*\\|\\s*"); - return Arrays.stream(strings).mapToInt(Integer::valueOf).toArray(); - } else { - throw new IllegalArgumentException("Conversion from " + source.getClass() - + " to " + targetType + " not supported."); - } - } - - } - @ParameterizedTest @CsvSource({ "0,1,-1,''", @@ -38,7 +18,7 @@ class AscendingRunsTest { "2,2,-2,0|1|-2|-1", "2,4,-2,0|1|2|3|-2|-1|0|1", }) - void testAscendingRuns1(int numOfRuns, int runLength, int decreaseBetweenRuns, @ConvertWith(IntArrayConverter.class) int[] expected) { + void testAscendingRuns1(int numOfRuns, int runLength, int decreaseBetweenRuns, @ConvertWith(JUnitUtil.IntArrayConverter.class) int[] expected) { Integer[] actualIntegers = AscendingRuns.newAscendingRuns(numOfRuns, runLength, decreaseBetweenRuns).getCopy(); int[] actual = Arrays.stream(actualIntegers).mapToInt(Integer::valueOf).toArray(); assertArrayEquals(expected, actual); diff --git a/app/src/test/java/de/uni_marburg/powersort/sort/ASortTest.java b/app/src/test/java/de/uni_marburg/powersort/sort/ASortTest.java new file mode 100644 index 0000000..dc7acf5 --- /dev/null +++ b/app/src/test/java/de/uni_marburg/powersort/sort/ASortTest.java @@ -0,0 +1,7 @@ +package de.uni_marburg.powersort.sort; + +public class ASortTest extends AbstractSortTest { + ASortTest() { + sortAlg = SortEnum.ASORT; + } +} diff --git a/app/src/test/java/de/uni_marburg/powersort/sort/AbstractSortTest.java b/app/src/test/java/de/uni_marburg/powersort/sort/AbstractSortTest.java new file mode 100644 index 0000000..b058a10 --- /dev/null +++ b/app/src/test/java/de/uni_marburg/powersort/sort/AbstractSortTest.java @@ -0,0 +1,46 @@ +package de.uni_marburg.powersort.sort; + +import de.uni_marburg.powersort.JUnitUtil; +import de.uni_marburg.powersort.data.AscendingRuns; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.converter.ConvertWith; +import org.junit.jupiter.params.provider.CsvSource; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +public abstract class AbstractSortTest { + SortEnum sortAlg; + + @ParameterizedTest + @CsvSource({ + "''", + "1337", + "3|2|1", + "1|1", + "2|1", + "2|1|2", + }) + void test1(@ConvertWith(JUnitUtil.IntegerArrayConverter.class) Integer[] array) { + sortAndCheckResult(array); + } + + @ParameterizedTest + @CsvSource({ + "3,7,-13", + "3,7,-3", + }) + void test2(int numOfRuns, int runLength, int decreaseBetweenRuns) { + Integer[] array = AscendingRuns.newAscendingRuns(numOfRuns, runLength, decreaseBetweenRuns).getCopy(); + sortAndCheckResult(array); + } + + void sortAndCheckResult(Integer[] array){ + Integer[] expected = Arrays.copyOf(array, array.length); + Arrays.sort(expected); + + sortAlg.get().sort(array); + assertArrayEquals(expected, array); + } +} diff --git a/app/src/test/java/de/uni_marburg/powersort/sort/FinnSortTest.java b/app/src/test/java/de/uni_marburg/powersort/sort/FinnSortTest.java new file mode 100644 index 0000000..17578ac --- /dev/null +++ b/app/src/test/java/de/uni_marburg/powersort/sort/FinnSortTest.java @@ -0,0 +1,7 @@ +package de.uni_marburg.powersort.sort; + +public class FinnSortTest extends AbstractSortTest { + FinnSortTest() { + sortAlg = SortEnum.FIN_SORT; + } +}