diff --git a/code/libraries/array/src/main/java/nu/marginalia/array/algo/IntArraySort.java b/code/libraries/array/src/main/java/nu/marginalia/array/algo/IntArraySort.java index eb64e0a6..89905ea6 100644 --- a/code/libraries/array/src/main/java/nu/marginalia/array/algo/IntArraySort.java +++ b/code/libraries/array/src/main/java/nu/marginalia/array/algo/IntArraySort.java @@ -48,27 +48,10 @@ public interface IntArraySort extends IntArrayBase { return true; } - - default void insertionSort(long start, long end) { assert end - start < Integer.MAX_VALUE; - int n = (int) (end - start); - - if (n <= 1) { - return; - } - - for (int i = 1; i < n; i++) { - int key = get(start + i); - - int j = i - 1; - while (j >= 0 && get(start + j) > key) { - swap( start + j, start + (long)(j+1)); - j--; - } - set(start + j+1, key); - } + SortAlgoInsertionSort._insertionSort(this, start, end); } default void quickSort(long start, long end) { diff --git a/code/libraries/array/src/main/java/nu/marginalia/array/algo/LongArrayBase.java b/code/libraries/array/src/main/java/nu/marginalia/array/algo/LongArrayBase.java index c8431875..39d9bff7 100644 --- a/code/libraries/array/src/main/java/nu/marginalia/array/algo/LongArrayBase.java +++ b/code/libraries/array/src/main/java/nu/marginalia/array/algo/LongArrayBase.java @@ -70,6 +70,9 @@ public interface LongArrayBase extends BulkTransferArray { buffer[(int) i] = get(start + i); } } + default void get(long start, long[] buffer) { + get(start, start + buffer.length, buffer); + } void write(Path file) throws IOException; diff --git a/code/libraries/array/src/main/java/nu/marginalia/array/algo/SortAlgoInsertionSort.java b/code/libraries/array/src/main/java/nu/marginalia/array/algo/SortAlgoInsertionSort.java index b520542b..5980b5ac 100644 --- a/code/libraries/array/src/main/java/nu/marginalia/array/algo/SortAlgoInsertionSort.java +++ b/code/libraries/array/src/main/java/nu/marginalia/array/algo/SortAlgoInsertionSort.java @@ -14,15 +14,18 @@ class SortAlgoInsertionSort { return; } - for (int i = 1; i < span / sz; i++) { - long key = array.get(start + (long) i * sz); + long[] buf = new long[sz]; + for (long i = 1; i < span / sz; i++) { + array.get(start + i * sz, buf); + + long key = buf[0]; long j; - for (j = i - 1; j >= 0 && array.get(start + j* sz) > key; j--) { - array.swapn(sz, start + j *sz, start + (j + 1)*sz); + for (j = i - 1; j >= 0 && array.get(start + j * sz) > key; j--) { + shiftN(array, sz, start + j * sz, start + (j + 1) * sz, sz); } - array.set(start + (j + 1) * sz, key); + array.set(start + (j + 1) * sz, buf); } } @@ -40,9 +43,50 @@ class SortAlgoInsertionSort { int j; for (j = i - 1; j >= 0 && array.get(start + j) > key; j--) { - array.swap(start + j, start + j + 1); + shift(array, start + j, start + j + 1, 1); } + array.set(start + j + 1, key); } } + static void _insertionSort(IntArraySort array, long start, long end) { + assert end - start < Integer.MAX_VALUE; + + int n = (int) (end - start); + + if (n <= 1) { + return; + } + + for (int i = 1; i < n; i++) { + int key = array.get(start + i); + + int j; + for (j = i - 1; j >= 0 && array.get(start + j) > key; j--) { + shift(array, start + j, start + j + 1, 1); + } + + array.set(start + j + 1, key); + } + } + + private static void shiftN(LongArraySort array, int sz, long start, long end, long shift) { + for (long i = start; i < end; i+=sz) { + for (int j = 0; j < sz; j++) { + array.set(i + j + shift, array.get(i + j)); + } + } + } + private static void shift(LongArraySort array, long start, long end, long shift) { + for (long i = start; i < end; i++) { + array.set(i + shift, array.get(i)); + } + } + + private static void shift(IntArraySort array, long start, long end, long shift) { + for (long i = start; i < end; i++) { + array.set(i + shift, array.get(i)); + } + } + }