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

Commit 4683d4c9 authored by Tomasz Mikolajewski's avatar Tomasz Mikolajewski Committed by Android (Google) Code Review
Browse files

Merge "Precompute cursor indexes in DocumentsUI and improve perf by 2.7%." into nyc-dev

parents d08da04c 2e4e1478
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -151,6 +151,14 @@ public final class Shared {
        return sCollator.compare(lhs, rhs);
    }

    /**
     * Compare two strings against each other using system default collator in a
     * case-insensitive mode.
     */
    public static int compareToIgnoreCase(String lhs, String rhs) {
        return sCollator.compare(lhs, rhs);
    }

    public static boolean isHardwareKeyboardAvailable(Context context) {
        return context.getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS;
    }
+61 −30
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.State.SORT_ORDER_DISPLAY_NAME;
import static com.android.documentsui.State.SORT_ORDER_LAST_MODIFIED;
import static com.android.documentsui.State.SORT_ORDER_SIZE;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;

import android.database.Cursor;
import android.os.Bundle;
@@ -48,6 +46,7 @@ import java.util.Map;
@VisibleForTesting
public class Model {
    private static final String TAG = "Model";
    private static final String EMPTY = "";

    private boolean mIsLoading;
    private List<UpdateListener> mUpdateListeners = new ArrayList<>();
@@ -62,24 +61,17 @@ public class Model {
    private String mIds[] = new String[0];
    private int mSortOrder = SORT_ORDER_DISPLAY_NAME;

    private int mAuthorityIndex = -1;
    private int mDocIdIndex = -1;
    private int mMimeTypeIndex = -1;
    private int mDisplayNameIndex = -1;
    private int mSizeIndex = -1;
    private int mLastModifiedIndex = -1;

    @Nullable String info;
    @Nullable String error;
    @Nullable DocumentInfo doc;

    /**
     * Generates a Model ID for a cursor entry that refers to a document. The Model ID is a unique
     * string that can be used to identify the document referred to by the cursor.
     *
     * @param c A cursor that refers to a document.
     */
    private static String createModelId(Cursor c) {
        // TODO: Maybe more efficient to use just the document ID, in cases where there is only one
        // authority (which should be the majority of cases).
        return createModelId(
                getCursorString(c, RootCursorWrapper.COLUMN_AUTHORITY),
                getCursorString(c, Document.COLUMN_DOCUMENT_ID));
    }

    /**
     * Generates a Model ID for a cursor entry that refers to a document. The Model ID is a unique
     * string that can be used to identify the document referred to by the cursor.
@@ -127,6 +119,14 @@ public class Model {
        mCursor = result.cursor;
        mCursorCount = mCursor.getCount();
        mSortOrder = result.sortOrder;
        mAuthorityIndex = mCursor.getColumnIndex(RootCursorWrapper.COLUMN_AUTHORITY);
        assert(mAuthorityIndex != -1);
        mDocIdIndex = mCursor.getColumnIndex(Document.COLUMN_DOCUMENT_ID);
        mMimeTypeIndex = mCursor.getColumnIndex(Document.COLUMN_MIME_TYPE);
        mDisplayNameIndex = mCursor.getColumnIndex(Document.COLUMN_DISPLAY_NAME);
        mLastModifiedIndex = mCursor.getColumnIndex(Document.COLUMN_LAST_MODIFIED);
        mSizeIndex = mCursor.getColumnIndex(Document.COLUMN_SIZE);

        doc = result.doc;

        updateModelData();
@@ -173,22 +173,24 @@ public class Model {
        for (int pos = 0; pos < mCursorCount; ++pos) {
            mCursor.moveToNext();
            positions[pos] = pos;
            mIds[pos] = createModelId(mCursor);

            mimeType = getCursorString(mCursor, Document.COLUMN_MIME_TYPE);
            // Generates a Model ID for a cursor entry that refers to a document. The Model ID is a
            // unique string that can be used to identify the document referred to by the cursor.
            mIds[pos] = createModelId(
                    getStringOrEmpty(mAuthorityIndex), getStringOrEmpty(mDocIdIndex));

            mimeType = getStringOrEmpty(mMimeTypeIndex);
            isDirs[pos] = Document.MIME_TYPE_DIR.equals(mimeType);

            switch (mSortOrder) {
                case SORT_ORDER_DISPLAY_NAME:
                    final String displayName = getCursorString(
                            mCursor, Document.COLUMN_DISPLAY_NAME);
                    displayNames[pos] = displayName;
                    displayNames[pos] = getStringOrEmpty(mDisplayNameIndex);
                    break;
                case SORT_ORDER_LAST_MODIFIED:
                    longValues[pos] = getLastModified(mCursor);
                    longValues[pos] = getLastModified();
                    break;
                case SORT_ORDER_SIZE:
                    longValues[pos] = getCursorLong(mCursor, Document.COLUMN_SIZE);
                    longValues[pos] = getDocSize();
                    break;
            }
        }
@@ -244,7 +246,7 @@ public class Model {
                } else {
                    final String lhs = pivotValue;
                    final String rhs = sortKey[mid];
                    compare = Shared.compareToIgnoreCaseNullable(lhs, rhs);
                    compare = Shared.compareToIgnoreCase(lhs, rhs);
                }

                if (compare < 0) {
@@ -364,14 +366,43 @@ public class Model {
        }
    }

    /**
     * @return Value of the string column, or an empty string if no value, or empty value.
     */
    private String getStringOrEmpty(int columnIndex) {
        if (columnIndex == -1)
            return EMPTY;
        final String result = mCursor.getString(columnIndex);
        return result != null ? result : EMPTY;
    }

    /**
     * @return Timestamp for the given document. Some docs (e.g. active downloads) have a null
     * timestamp - these will be replaced with MAX_LONG so that such files get sorted to the top
     * when sorting by date.
     * or missing timestamp - these will be replaced with MAX_LONG so that such files get sorted to
     * the top when sorting by date.
     */
    private long getLastModified() {
        if (mLastModifiedIndex == -1)
            return Long.MAX_VALUE;
        try {
            final long result = mCursor.getLong(mLastModifiedIndex);
            return result > 0 ? result : Long.MAX_VALUE;
        } catch (NumberFormatException e) {
            return Long.MAX_VALUE;
        }
    }

    /**
     * @return Size for the given document. If the size is unknown or invalid, returns 0.
     */
    long getLastModified(Cursor cursor) {
        long l = getCursorLong(mCursor, Document.COLUMN_LAST_MODIFIED);
        return (l == -1) ? Long.MAX_VALUE : l;
    private long getDocSize() {
        if (mSizeIndex == -1)
            return 0;
        try {
            return mCursor.getLong(mSizeIndex);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    public @Nullable Cursor getItem(String modelId) {