Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f6a90ac authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Implement ResizableIntArray.fill"

parents 732edc1f 7abdcf1e
Loading
Loading
Loading
Loading
+49 −20
Original line number Original line Diff line number Diff line
@@ -28,38 +28,49 @@ public class ResizableIntArray {
    }
    }


    public int get(final int index) {
    public int get(final int index) {
        if (index < 0 || index >= mLength) {
        if (index < mLength) {
            throw new ArrayIndexOutOfBoundsException("length=" + mLength + "; index=" + index);
        }
            return mArray[index];
            return mArray[index];
        }
        }
        throw new ArrayIndexOutOfBoundsException("length=" + mLength + "; index=" + index);
    }


    public void add(final int index, final int val) {
    public void add(final int index, final int val) {
        if (mLength < index + 1) {
        if (index < mLength) {
            mArray[index] = val;
        } else {
            mLength = index;
            mLength = index;
            add(val);
            add(val);
        } else {
            mArray[index] = val;
        }
        }
    }
    }


    public void add(final int val) {
    public void add(final int val) {
        final int nextLength = mLength + 1;
        final int currentLength = mLength;
        ensureCapacity(nextLength);
        ensureCapacity(currentLength + 1);
        mArray[mLength] = val;
        mArray[currentLength] = val;
        mLength = nextLength;
        mLength = currentLength + 1;
    }

    /**
     * Calculate the new capacity of {@code mArray}.
     * @param minimumCapacity the minimum capacity that the {@code mArray} should have.
     * @return the new capacity that the {@code mArray} should have. Returns zero when there is no
     * need to expand {@code mArray}.
     */
    private int calculateCapacity(final int minimumCapacity) {
        final int currentCapcity = mArray.length;
        if (currentCapcity < minimumCapacity) {
            final int nextCapacity = currentCapcity * 2;
            // The following is the same as return Math.max(minimumCapacity, nextCapacity);
            return minimumCapacity > nextCapacity ? minimumCapacity : nextCapacity;
        }
        return 0;
    }
    }


    private void ensureCapacity(final int minimumCapacity) {
    private void ensureCapacity(final int minimumCapacity) {
        if (mArray.length < minimumCapacity) {
        final int newCapacity = calculateCapacity(minimumCapacity);
            final int nextCapacity = mArray.length * 2;
        if (newCapacity > 0) {
            // The following is the same as newLength =
            // Math.max(minimumCapacity, nextCapacity);
            final int newLength = minimumCapacity > nextCapacity
                    ? minimumCapacity
                    : nextCapacity;
            // TODO: Implement primitive array pool.
            // TODO: Implement primitive array pool.
            mArray = Arrays.copyOf(mArray, newLength);
            mArray = Arrays.copyOf(mArray, newCapacity);
        }
        }
    }
    }


@@ -89,17 +100,35 @@ public class ResizableIntArray {
    }
    }


    public void copy(final ResizableIntArray ip) {
    public void copy(final ResizableIntArray ip) {
        // TODO: Avoid useless coping of values.
        final int newCapacity = calculateCapacity(ip.mLength);
        ensureCapacity(ip.mLength);
        if (newCapacity > 0) {
            // TODO: Implement primitive array pool.
            mArray = new int[newCapacity];
        }
        System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength);
        System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength);
        mLength = ip.mLength;
        mLength = ip.mLength;
    }
    }


    public void append(final ResizableIntArray src, final int startPos, final int length) {
    public void append(final ResizableIntArray src, final int startPos, final int length) {
        if (length == 0) {
            return;
        }
        final int currentLength = mLength;
        final int currentLength = mLength;
        final int newLength = currentLength + length;
        final int newLength = currentLength + length;
        ensureCapacity(newLength);
        ensureCapacity(newLength);
        System.arraycopy(src.mArray, startPos, mArray, currentLength, length);
        System.arraycopy(src.mArray, startPos, mArray, currentLength, length);
        mLength = newLength;
        mLength = newLength;
    }
    }

    public void fill(final int value, final int startPos, final int length) {
        if (startPos < 0 || length < 0) {
            throw new IllegalArgumentException("startPos=" + startPos + "; length=" + length);
        }
        final int endPos = startPos + length;
        ensureCapacity(endPos);
        Arrays.fill(mArray, startPos, endPos, value);
        if (mLength < endPos) {
            mLength = endPos;
        }
    }
}
}
+89 −8
Original line number Original line Diff line number Diff line
@@ -37,8 +37,12 @@ public class ResizableIntArrayTests extends AndroidTestCase {
        for (int i = 0; i < limit; i++) {
        for (int i = 0; i < limit; i++) {
            src.add(i);
            src.add(i);
            assertEquals("length after add " + i, i + 1, src.getLength());
            assertEquals("length after add " + i, i + 1, src.getLength());
            if (i == DEFAULT_CAPACITY) array2 = src.getPrimitiveArray();
            if (i == DEFAULT_CAPACITY) {
            if (i == DEFAULT_CAPACITY * 2) array3 = src.getPrimitiveArray();
                array2 = src.getPrimitiveArray();
            }
            if (i == DEFAULT_CAPACITY * 2) {
                array3 = src.getPrimitiveArray();
            }
            if (i < DEFAULT_CAPACITY) {
            if (i < DEFAULT_CAPACITY) {
                assertSame("array after add " + i, array, src.getPrimitiveArray());
                assertSame("array after add " + i, array, src.getPrimitiveArray());
            } else if (i < DEFAULT_CAPACITY * 2) {
            } else if (i < DEFAULT_CAPACITY * 2) {
@@ -110,7 +114,9 @@ public class ResizableIntArrayTests extends AndroidTestCase {
        for (int i = 0; i < DEFAULT_CAPACITY; i++) {
        for (int i = 0; i < DEFAULT_CAPACITY; i++) {
            src.add(i);
            src.add(i);
            assertEquals("length after add " + i, i + 1, src.getLength());
            assertEquals("length after add " + i, i + 1, src.getLength());
            if (i == smallerLength) array3 = src.getPrimitiveArray();
            if (i == smallerLength) {
                array3 = src.getPrimitiveArray();
            }
            if (i < smallerLength) {
            if (i < smallerLength) {
                assertSame("array after add " + i, array2, src.getPrimitiveArray());
                assertSame("array after add " + i, array2, src.getPrimitiveArray());
            } else if (i < smallerLength * 2) {
            } else if (i < smallerLength * 2) {
@@ -133,11 +139,13 @@ public class ResizableIntArrayTests extends AndroidTestCase {
        assertEquals("length after larger setLength", largerLength, src.getLength());
        assertEquals("length after larger setLength", largerLength, src.getLength());
        assertNotSame("array after larger setLength", array, array2);
        assertNotSame("array after larger setLength", array, array2);
        assertEquals("array length after larger setLength", largerLength, array2.length);
        assertEquals("array length after larger setLength", largerLength, array2.length);
        for (int i = 0; i < DEFAULT_CAPACITY; i++) {
        for (int i = 0; i < largerLength; i++) {
            assertEquals("value at " + i, i, src.get(i));
            final int v = src.get(i);
            if (i < DEFAULT_CAPACITY) {
                assertEquals("value at " + i, i, v);
            } else {
                assertEquals("value at " + i, 0, v);
            }
            }
        for (int i = DEFAULT_CAPACITY; i < largerLength; i++) {
            assertEquals("value at " + i, 0, src.get(i));
        }
        }


        final int smallerLength = DEFAULT_CAPACITY / 2;
        final int smallerLength = DEFAULT_CAPACITY / 2;
@@ -236,6 +244,79 @@ public class ResizableIntArrayTests extends AndroidTestCase {
                src.getPrimitiveArray(), 0, dst.getPrimitiveArray(), dstLen + srcLen, srcLen);
                src.getPrimitiveArray(), 0, dst.getPrimitiveArray(), dstLen + srcLen, srcLen);
    }
    }


    public void testFill() {
        final int srcLen = DEFAULT_CAPACITY;
        final ResizableIntArray src = new ResizableIntArray(srcLen);
        for (int i = 0; i < srcLen; i++) {
            src.add(i);
        }
        final int[] array = src.getPrimitiveArray();

        final int startPos = srcLen / 3;
        final int length = srcLen / 3;
        final int endPos = startPos + length;
        assertTrue(startPos >= 1);
        final int value = 123;
        try {
            src.fill(value, -1, length);
            fail("fill from -1 shouldn't succeed");
        } catch (IllegalArgumentException e) {
            // success
        }
        try {
            src.fill(value, startPos, -1);
            fail("fill negative length shouldn't succeed");
        } catch (IllegalArgumentException e) {
            // success
        }

        src.fill(value, startPos, length);
        assertEquals("length after fill", srcLen, src.getLength());
        assertSame("array after fill", array, src.getPrimitiveArray());
        for (int i = 0; i < srcLen; i++) {
            final int v = src.get(i);
            if (i >= startPos && i < endPos) {
                assertEquals("new values after fill at " + i, value, v);
            } else {
                assertEquals("unmodified values after fill at " + i, i, v);
            }
        }

        final int length2 = srcLen * 2 - startPos;
        final int largeEnd = startPos + length2;
        assertTrue(largeEnd > srcLen);
        final int value2 = 456;
        src.fill(value2, startPos, length2);
        assertEquals("length after large fill", largeEnd, src.getLength());
        assertNotSame("array after large fill", array, src.getPrimitiveArray());
        for (int i = 0; i < largeEnd; i++) {
            final int v = src.get(i);
            if (i >= startPos && i < largeEnd) {
                assertEquals("new values after large fill at " + i, value2, v);
            } else {
                assertEquals("unmodified values after large fill at " + i, i, v);
            }
        }

        final int startPos2 = largeEnd + length2;
        final int endPos2 = startPos2 + length2;
        final int value3 = 789;
        src.fill(value3, startPos2, length2);
        assertEquals("length after disjoint fill", endPos2, src.getLength());
        for (int i = 0; i < endPos2; i++) {
            final int v = src.get(i);
            if (i >= startPos2 && i < endPos2) {
                assertEquals("new values after disjoint fill at " + i, value3, v);
            } else if (i >= startPos && i < largeEnd) {
                assertEquals("unmodified values after disjoint fill at " + i, value2, v);
            } else if (i < startPos) {
                assertEquals("unmodified values after disjoint fill at " + i, i, v);
            } else {
                assertEquals("gap values after disjoint fill at " + i, 0, v);
            }
        }
    }

    private static void assertArrayEquals(String message, int[] expecteds, int expectedPos,
    private static void assertArrayEquals(String message, int[] expecteds, int expectedPos,
            int[] actuals, int actualPos, int length) {
            int[] actuals, int actualPos, int length) {
        if (expecteds == null && actuals == null) {
        if (expecteds == null && actuals == null) {