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

Commit 44b3697c authored by Lee Shombert's avatar Lee Shombert
Browse files

A space-efficient 2D matrix - clean up

Bug: Bug: 188447813

Convert WatchedSparseBooleanMatrix to pack bits into ints instead of
bytes.  This eliminates a lot of casts and it is probably slightly
faster.

Force the control information arrays in the matrix to resize in step
with the values array.  The default behavior of GrowingArrayUtils is
to double the size of an array when it needs to grow, which is
unnecessarily large.  Also, the control arrays are shrunk along with
the value array.

Use the ArrayUtils methods for array allocation.  This is consistent
with classes in android.util.

Test: atest
 * CtsContentTestCases:IntentFilterTest
 * CtsDynamicMimeHostTestCases
 * CtsRoleTestCases
 * FrameworksServicesTests:UserSystemPackageInstallerTest
 * FrameworksServicesTests:PackageManagerSettingsTests
 * FrameworksServicesTests:PackageManagerServiceTest
 * FrameworksServicesTests:AppsFilterTest
 * FrameworksServicesTests:PackageInstallerSessionTest
 * FrameworksServicesTests:ScanTests
 * UserLifecycleTests#startUser
 * UserLifecycleTests#stopUser
 * UserLifecycleTests#switchUser
 * FrameworksServicesTests:WatcherTest
 * android.appsecurity.cts.EphemeralTest
 * android.appsecurity.cts.InstantAppUserTest

Change-Id: I8427905361e1471c91433c77628aa34b12b1044d
parent e571aacd
Loading
Loading
Loading
Loading
+45 −34
Original line number Original line Diff line number Diff line
@@ -67,7 +67,8 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
     * <ul>
     * <ul>
     * <li> The matrix does not automatically shrink but there is a compress() method that
     * <li> The matrix does not automatically shrink but there is a compress() method that
     *      will recover unused space.
     *      will recover unused space.
     * <li> Equality is a very, very expesive operation.
     * <li> Equality is a very, very expensive operation because it must walk the matrices
     *      beimg compared element by element.
     * </ul>
     * </ul>
     */
     */


@@ -79,10 +80,9 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
    static final int STEP = 64;
    static final int STEP = 64;


    /**
    /**
     * There are 8 bits in a byte.  The constant is defined here only to make it easy to
     * The number of bits in the mValues array element.
     * find in the code.
     */
     */
    private static final int BYTE = 8;
    private static final int PACKING = 32;


    /**
    /**
     * Constants that index into the string array returned by matrixToString.  The primary
     * Constants that index into the string array returned by matrixToString.  The primary
@@ -123,7 +123,7 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
    /**
    /**
     * The boolean array.  This array is always {@code mOrder x mOrder} in size.
     * The boolean array.  This array is always {@code mOrder x mOrder} in size.
     */
     */
    private byte[] mValues;
    private int[] mValues;


    /**
    /**
     * A convenience function called when the elements are added to or removed from the storage.
     * A convenience function called when the elements are added to or removed from the storage.
@@ -157,10 +157,10 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
            throw new RuntimeException("mOrder is " + mOrder + " initCap is " + initialCapacity);
            throw new RuntimeException("mOrder is " + mOrder + " initCap is " + initialCapacity);
        }
        }


        mInUse = new boolean[mOrder];
        mInUse = ArrayUtils.newUnpaddedBooleanArray(mOrder);
        mKeys = ArrayUtils.newUnpaddedIntArray(mOrder);
        mKeys = ArrayUtils.newUnpaddedIntArray(mOrder);
        mMap = ArrayUtils.newUnpaddedIntArray(mOrder);
        mMap = ArrayUtils.newUnpaddedIntArray(mOrder);
        mValues = new byte[mOrder * mOrder / 8];
        mValues = ArrayUtils.newUnpaddedIntArray(mOrder * mOrder / PACKING);
        mSize = 0;
        mSize = 0;
    }
    }


@@ -301,8 +301,8 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
     */
     */
    private boolean valueAtInternal(int row, int col) {
    private boolean valueAtInternal(int row, int col) {
        int element = row * mOrder + col;
        int element = row * mOrder + col;
        int offset = element / BYTE;
        int offset = element / PACKING;
        int mask = 1 << (element % BYTE);
        int mask = 1 << (element % PACKING);
        return (mValues[offset] & mask) != 0;
        return (mValues[offset] & mask) != 0;
    }
    }


@@ -324,8 +324,8 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
     */
     */
    private void setValueAtInternal(int row, int col, boolean value) {
    private void setValueAtInternal(int row, int col, boolean value) {
        int element = row * mOrder + col;
        int element = row * mOrder + col;
        int offset = element / BYTE;
        int offset = element / PACKING;
        byte mask = (byte) (1 << (element % BYTE));
        int mask = 1 << (element % PACKING);
        if (value) {
        if (value) {
            mValues[offset] |= mask;
            mValues[offset] |= mask;
        } else {
        } else {
@@ -377,10 +377,10 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
            mSize++;
            mSize++;


            // Initialize the row and column corresponding to the new index.
            // Initialize the row and column corresponding to the new index.
            int valueRow = mOrder / BYTE;
            int valueRow = mOrder / PACKING;
            int offset = newIndex / BYTE;
            int offset = newIndex / PACKING;
            byte mask = (byte) (~(1 << (newIndex % BYTE)));
            int mask = ~(1 << (newIndex % PACKING));
            Arrays.fill(mValues, newIndex * valueRow, (newIndex + 1) * valueRow, (byte) 0);
            Arrays.fill(mValues, newIndex * valueRow, (newIndex + 1) * valueRow, 0);
            for (int n = 0; n < mSize; n++) {
            for (int n = 0; n < mSize; n++) {
                mValues[n * valueRow + offset] &= mask;
                mValues[n * valueRow + offset] &= mask;
            }
            }
@@ -412,25 +412,36 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
     * Expand the 2D array.  This also extends the free list.
     * Expand the 2D array.  This also extends the free list.
     */
     */
    private void growMatrix() {
    private void growMatrix() {
        resizeValues(mOrder + STEP);
        resizeMatrix(mOrder + STEP);
    }
    }


    /**
    /**
     * Resize the values array to the new dimension.
     * Resize the values array to the new dimension.
     */
     */
    private void resizeValues(int newOrder) {
    private void resizeMatrix(int newOrder) {

        if (newOrder % STEP != 0) {
        boolean[] newInuse = Arrays.copyOf(mInUse, newOrder);
            throw new IllegalArgumentException("matrix order " + newOrder
                                               + " is not a multiple of " + STEP);
        }
        int minOrder = Math.min(mOrder, newOrder);
        int minOrder = Math.min(mOrder, newOrder);


        byte[] newValues = new byte[newOrder * newOrder / BYTE];
        boolean[] newInUse = ArrayUtils.newUnpaddedBooleanArray(newOrder);
        System.arraycopy(mInUse, 0, newInUse, 0, minOrder);
        int[] newMap = ArrayUtils.newUnpaddedIntArray(newOrder);
        System.arraycopy(mMap, 0, newMap, 0, minOrder);
        int[] newKeys = ArrayUtils.newUnpaddedIntArray(newOrder);
        System.arraycopy(mKeys, 0, newKeys, 0, minOrder);

        int[] newValues = ArrayUtils.newUnpaddedIntArray(newOrder * newOrder / PACKING);
        for (int i = 0; i < minOrder; i++) {
        for (int i = 0; i < minOrder; i++) {
            int row = mOrder * i / BYTE;
            int row = mOrder * i / PACKING;
            int newRow = newOrder * i / BYTE;
            int newRow = newOrder * i / PACKING;
            System.arraycopy(mValues, row, newValues, newRow, minOrder / BYTE);
            System.arraycopy(mValues, row, newValues, newRow, minOrder / PACKING);
        }
        }


        mInUse = newInuse;
        mInUse = newInUse;
        mMap = newMap;
        mKeys = newKeys;
        mValues = newValues;
        mValues = newValues;
        mOrder = newOrder;
        mOrder = newOrder;
    }
    }
@@ -482,21 +493,21 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
            int src = mMap[srcIndex];
            int src = mMap[srcIndex];
            mInUse[src] = false;
            mInUse[src] = false;
            mMap[srcIndex] = dst;
            mMap[srcIndex] = dst;
            System.arraycopy(mValues, src * mOrder / BYTE,
            System.arraycopy(mValues, src * mOrder / PACKING,
                             mValues, dst * mOrder / BYTE,
                             mValues, dst * mOrder / PACKING,
                             mOrder / BYTE);
                             mOrder / PACKING);
            int srcOffset = (src / BYTE);
            int srcOffset = (src / PACKING);
            byte srcMask = (byte) (1 << (src % BYTE));
            int srcMask = 1 << (src % PACKING);
            int dstOffset = (dst / BYTE);
            int dstOffset = (dst / PACKING);
            byte dstMask = (byte) (1 << (dst % BYTE));
            int dstMask = 1 << (dst % PACKING);
            for (int i = 0; i < mOrder; i++) {
            for (int i = 0; i < mOrder; i++) {
                if ((mValues[srcOffset] & srcMask) == 0) {
                if ((mValues[srcOffset] & srcMask) == 0) {
                    mValues[dstOffset] &= ~dstMask;
                    mValues[dstOffset] &= ~dstMask;
                } else {
                } else {
                    mValues[dstOffset] |= dstMask;
                    mValues[dstOffset] |= dstMask;
                }
                }
                srcOffset += mOrder / BYTE;
                srcOffset += mOrder / PACKING;
                dstOffset += mOrder / BYTE;
                dstOffset += mOrder / PACKING;
            }
            }
        }
        }
    }
    }
@@ -508,7 +519,7 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab
        pack();
        pack();
        int unused = (mOrder - mSize) / STEP;
        int unused = (mOrder - mSize) / STEP;
        if (unused > 0) {
        if (unused > 0) {
            resizeValues(mOrder - (unused * STEP));
            resizeMatrix(mOrder - (unused * STEP));
        }
        }
    }
    }