Merge "Precompute cursor indexes in DocumentsUI and improve perf by 2.7%." into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4683d4c914
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
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) {
|
||||
@@ -365,13 +367,42 @@ public class Model {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @return Value of the string column, or an empty string if no value, or empty value.
|
||||
*/
|
||||
long getLastModified(Cursor cursor) {
|
||||
long l = getCursorLong(mCursor, Document.COLUMN_LAST_MODIFIED);
|
||||
return (l == -1) ? Long.MAX_VALUE : l;
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
private long getDocSize() {
|
||||
if (mSizeIndex == -1)
|
||||
return 0;
|
||||
try {
|
||||
return mCursor.getLong(mSizeIndex);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable Cursor getItem(String modelId) {
|
||||
|
||||
Reference in New Issue
Block a user