diff --git a/primitiveCollections/src/main/java/org/lucares/collections/IntList.java b/primitiveCollections/src/main/java/org/lucares/collections/IntList.java index 1bf3a6a..767c2cb 100644 --- a/primitiveCollections/src/main/java/org/lucares/collections/IntList.java +++ b/primitiveCollections/src/main/java/org/lucares/collections/IntList.java @@ -200,6 +200,22 @@ public final class IntList implements Serializable, Cloneable { size++; } + /** + * Unsafe version of {@link #add(int)} that does not call + * {@link #ensureCapacity(int)}. The caller has to make sure that the list has + * capacity. + * + * @param value the value to add + */ + private void addUnsafe(final int value) { + data[size] = value; + + if (sorted) { + sorted = size == 0 ? sorted : data[size - 1] <= data[size]; + } + size++; + } + /** * Inserts {@code values} at position {@code pos} into the list. * @@ -554,6 +570,19 @@ public final class IntList implements Serializable, Cloneable { return data[pos]; } + /** + * Unsafe version of {@link #get(int)} that does not check for out of bounds + * access if assertions are disabled. The caller has to make sure that pos is + * not negative and smaller than {@link #size()}. + * + * @param pos position of the element to return + * @return the element at position {@code pos} + */ + private int getUnsafe(final int pos) { + assert pos >= 0 && pos < size : "index out of bounds at " + pos; + return data[pos]; + } + /** * Returns the {@code length} elements starting at {@code from}. * @@ -1091,30 +1120,30 @@ public final class IntList implements Serializable, Cloneable { while (l < aSize && r < bSize) { - final int lv = a.get(l); - final int rv = b.get(r); + final int lv = a.getUnsafe(l); + final int rv = b.getUnsafe(r); if (lv < rv) { - result.add(lv); + result.addUnsafe(lv); l++; - while (l < aSize && lv == a.get(l)) { + while (l < aSize && lv == a.getUnsafe(l)) { l++; } } else if (lv > rv) { - result.add(rv); + result.addUnsafe(rv); r++; - while (r < bSize && rv == b.get(r)) { + while (r < bSize && rv == b.getUnsafe(r)) { r++; } } else { - result.add(lv); + result.addUnsafe(lv); l++; r++; - while (l < aSize && lv == a.get(l)) { + while (l < aSize && lv == a.getUnsafe(l)) { l++; } - while (r < bSize && rv == b.get(r)) { + while (r < bSize && rv == b.getUnsafe(r)) { r++; } } @@ -1122,15 +1151,17 @@ public final class IntList implements Serializable, Cloneable { // add remaining values from list a, if any exist for (; l < aSize; l++) { - if (l == 0 || a.get(l) != a.get(l - 1)) { - result.add(a.get(l)); + final int valueAtPosL = a.getUnsafe(l); + if (l == 0 || valueAtPosL != a.getUnsafe(l - 1)) { + result.addUnsafe(valueAtPosL); } } // add remaining values from list b, if any exist for (; r < bSize; r++) { - if (r == 0 || b.get(r) != b.get(r - 1)) { - result.add(b.get(r)); + final int valueAtPosR = b.getUnsafe(r); + if (r == 0 || valueAtPosR != b.getUnsafe(r - 1)) { + result.addUnsafe(valueAtPosR); } } diff --git a/primitiveCollections/src/main/java/org/lucares/collections/LongList.java b/primitiveCollections/src/main/java/org/lucares/collections/LongList.java index e2e7c84..a7ad2fd 100644 --- a/primitiveCollections/src/main/java/org/lucares/collections/LongList.java +++ b/primitiveCollections/src/main/java/org/lucares/collections/LongList.java @@ -190,6 +190,22 @@ public final class LongList implements Serializable, Cloneable { size++; } + /** + * Unsafe version of {@link #add(long)} that does not call + * {@link #ensureCapacity(long)}. The caller has to make sure that the list has + * capacity. + * + * @param value the value to add + */ + private void addUnsafe(final long value) { + data[size] = value; + + if (sorted) { + sorted = size == 0 ? sorted : data[size - 1] <= data[size]; + } + size++; + } + /** * Inserts {@code values} at position {@code pos} into the list. * @@ -383,7 +399,7 @@ public final class LongList implements Serializable, Cloneable { /** * Add all values of the given lists. - * + * * @param longLists collection of the lists * @throws NullPointerException if the collection of {@link LongList} is null or * contains null @@ -559,6 +575,19 @@ public final class LongList implements Serializable, Cloneable { return data[pos]; } + /** + * Unsafe version of {@link #get(long)} that does not check for out of bounds + * access if assertions are disabled. The caller has to make sure that pos is + * not negative and smaller than {@link #size()}. + * + * @param pos position of the element to return + * @return the element at position {@code pos} + */ + private long getUnsafe(final int pos) { + assert pos >= 0 && pos < size : "index out of bounds at " + pos; + return data[pos]; + } + /** * Returns the {@code length} elements starting at {@code from}. * @@ -1090,30 +1119,30 @@ public final class LongList implements Serializable, Cloneable { while (l < aSize && r < bSize) { - final long lv = a.get(l); - final long rv = b.get(r); + final long lv = a.getUnsafe(l); + final long rv = b.getUnsafe(r); if (lv < rv) { - result.add(lv); + result.addUnsafe(lv); l++; - while (l < aSize && lv == a.get(l)) { + while (l < aSize && lv == a.getUnsafe(l)) { l++; } } else if (lv > rv) { - result.add(rv); + result.addUnsafe(rv); r++; - while (r < bSize && rv == b.get(r)) { + while (r < bSize && rv == b.getUnsafe(r)) { r++; } } else { - result.add(lv); + result.addUnsafe(lv); l++; r++; - while (l < aSize && lv == a.get(l)) { + while (l < aSize && lv == a.getUnsafe(l)) { l++; } - while (r < bSize && rv == b.get(r)) { + while (r < bSize && rv == b.getUnsafe(r)) { r++; } } @@ -1121,15 +1150,17 @@ public final class LongList implements Serializable, Cloneable { // add remaining values from list a, if any exist for (; l < aSize; l++) { - if (l == 0 || a.get(l) != a.get(l - 1)) { - result.add(a.get(l)); + final long valueAtPosL = a.getUnsafe(l); + if (l == 0 || valueAtPosL != a.getUnsafe(l - 1)) { + result.addUnsafe(valueAtPosL); } } // add remaining values from list b, if any exist for (; r < bSize; r++) { - if (r == 0 || b.get(r) != b.get(r - 1)) { - result.add(b.get(r)); + final long valueAtPosR = b.getUnsafe(r); + if (r == 0 || valueAtPosR != b.getUnsafe(r - 1)) { + result.addUnsafe(valueAtPosR); } }