Merge "Improve sorting performance by 2.5 times." into nyc-dev

This commit is contained in:
Tomasz Mikolajewski
2016-03-10 00:28:23 +00:00
committed by Android (Google) Code Review
5 changed files with 36 additions and 40 deletions

View File

@@ -113,8 +113,8 @@ final class QuickViewIntentBuilder {
} }
private int collectViewableUris(ArrayList<Uri> uris) { private int collectViewableUris(ArrayList<Uri> uris) {
final List<String> siblingIds = mModel.getModelIds(); final String[] siblingIds = mModel.getModelIds();
uris.ensureCapacity(siblingIds.size()); uris.ensureCapacity(siblingIds.length);
int documentLocation = 0; int documentLocation = 0;
Cursor cursor; Cursor cursor;
@@ -124,8 +124,8 @@ final class QuickViewIntentBuilder {
Uri uri; Uri uri;
// Cursor's are not guaranteed to be immutable. Hence, traverse it only once. // Cursor's are not guaranteed to be immutable. Hence, traverse it only once.
for (int i = 0; i < siblingIds.size(); i++) { for (int i = 0; i < siblingIds.length; i++) {
cursor = mModel.getItem(siblingIds.get(i)); cursor = mModel.getItem(siblingIds[i]);
mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
if (Document.MIME_TYPE_DIR.equals(mimeType)) { if (Document.MIME_TYPE_DIR.equals(mimeType)) {

View File

@@ -59,7 +59,7 @@ public class Model {
* A sorted array of model IDs for the files currently in the Model. Sort order is determined * A sorted array of model IDs for the files currently in the Model. Sort order is determined
* by {@link #mSortOrder} * by {@link #mSortOrder}
*/ */
private List<String> mIds = new ArrayList<>(); private String mIds[] = new String[0];
private int mSortOrder = SORT_ORDER_DISPLAY_NAME; private int mSortOrder = SORT_ORDER_DISPLAY_NAME;
@Nullable String info; @Nullable String info;
@@ -108,7 +108,7 @@ public class Model {
if (result == null) { if (result == null) {
mCursor = null; mCursor = null;
mCursorCount = 0; mCursorCount = 0;
mIds.clear(); mIds = new String[0];
mPositions.clear(); mPositions.clear();
info = null; info = null;
error = null; error = null;
@@ -152,7 +152,7 @@ public class Model {
*/ */
private void updateModelData() { private void updateModelData() {
int[] positions = new int[mCursorCount]; int[] positions = new int[mCursorCount];
mIds.clear(); mIds = new String[mCursorCount];
String[] stringValues = new String[mCursorCount]; String[] stringValues = new String[mCursorCount];
long[] longValues = null; long[] longValues = null;
@@ -164,7 +164,7 @@ public class Model {
for (int pos = 0; pos < mCursorCount; ++pos) { for (int pos = 0; pos < mCursorCount; ++pos) {
mCursor.moveToNext(); mCursor.moveToNext();
positions[pos] = pos; positions[pos] = pos;
mIds.add(createModelId(mCursor)); mIds[pos] = createModelId(mCursor);
switch(mSortOrder) { switch(mSortOrder) {
case SORT_ORDER_DISPLAY_NAME: case SORT_ORDER_DISPLAY_NAME:
@@ -201,7 +201,7 @@ public class Model {
// Populate the positions. // Populate the positions.
mPositions.clear(); mPositions.clear();
for (int i = 0; i < mCursorCount; ++i) { for (int i = 0; i < mCursorCount; ++i) {
mPositions.put(mIds.get(i), positions[i]); mPositions.put(mIds[i], positions[i]);
} }
} }
@@ -214,12 +214,12 @@ public class Model {
* @param positions Cursor positions to be sorted. * @param positions Cursor positions to be sorted.
* @param ids Model IDs to be sorted. * @param ids Model IDs to be sorted.
*/ */
private static void binarySort(String[] sortKey, int[] positions, List<String> ids) { private static void binarySort(String[] sortKey, int[] positions, String[] ids) {
final int count = positions.length; final int count = positions.length;
for (int start = 1; start < count; start++) { for (int start = 1; start < count; start++) {
final int pivotPosition = positions[start]; final int pivotPosition = positions[start];
final String pivotValue = sortKey[start]; final String pivotValue = sortKey[start];
final String pivotId = ids.get(start); final String pivotId = ids[start];
int left = 0; int left = 0;
int right = start; int right = start;
@@ -243,23 +243,21 @@ public class Model {
case 2: case 2:
positions[left + 2] = positions[left + 1]; positions[left + 2] = positions[left + 1];
sortKey[left + 2] = sortKey[left + 1]; sortKey[left + 2] = sortKey[left + 1];
ids.set(left + 2, ids.get(left + 1)); ids[left + 2] = ids[left + 1];
case 1: case 1:
positions[left + 1] = positions[left]; positions[left + 1] = positions[left];
sortKey[left + 1] = sortKey[left]; sortKey[left + 1] = sortKey[left];
ids.set(left + 1, ids.get(left)); ids[left + 1] = ids[left];
break; break;
default: default:
System.arraycopy(positions, left, positions, left + 1, n); System.arraycopy(positions, left, positions, left + 1, n);
System.arraycopy(sortKey, left, sortKey, left + 1, n); System.arraycopy(sortKey, left, sortKey, left + 1, n);
for (int i = n; i >= 1; --i) { System.arraycopy(ids, left, ids, left + 1, n);
ids.set(left + i, ids.get(left + i - 1));
}
} }
positions[left] = pivotPosition; positions[left] = pivotPosition;
sortKey[left] = pivotValue; sortKey[left] = pivotValue;
ids.set(left, pivotId); ids[left] = pivotId;
} }
} }
@@ -275,13 +273,13 @@ public class Model {
* @param ids Model IDs to be sorted. * @param ids Model IDs to be sorted.
*/ */
private static void binarySort( private static void binarySort(
long[] sortKey, String[] mimeTypes, int[] positions, List<String> ids) { long[] sortKey, String[] mimeTypes, int[] positions, String[] ids) {
final int count = positions.length; final int count = positions.length;
for (int start = 1; start < count; start++) { for (int start = 1; start < count; start++) {
final int pivotPosition = positions[start]; final int pivotPosition = positions[start];
final long pivotValue = sortKey[start]; final long pivotValue = sortKey[start];
final String pivotMime = mimeTypes[start]; final String pivotMime = mimeTypes[start];
final String pivotId = ids.get(start); final String pivotId = ids[start];
int left = 0; int left = 0;
int right = start; int right = start;
@@ -310,7 +308,7 @@ public class Model {
// have identical numerical sort keys. One common example of this scenario is seen // have identical numerical sort keys. One common example of this scenario is seen
// when sorting a set of active downloads by mod time. // when sorting a set of active downloads by mod time.
if (compare == 0) { if (compare == 0) {
compare = pivotId.compareTo(ids.get(mid)); compare = pivotId.compareTo(ids[mid]);
} }
if (compare < 0) { if (compare < 0) {
@@ -326,26 +324,24 @@ public class Model {
positions[left + 2] = positions[left + 1]; positions[left + 2] = positions[left + 1];
sortKey[left + 2] = sortKey[left + 1]; sortKey[left + 2] = sortKey[left + 1];
mimeTypes[left + 2] = mimeTypes[left + 1]; mimeTypes[left + 2] = mimeTypes[left + 1];
ids.set(left + 2, ids.get(left + 1)); ids[left + 2] = ids[left + 1];
case 1: case 1:
positions[left + 1] = positions[left]; positions[left + 1] = positions[left];
sortKey[left + 1] = sortKey[left]; sortKey[left + 1] = sortKey[left];
mimeTypes[left + 1] = mimeTypes[left]; mimeTypes[left + 1] = mimeTypes[left];
ids.set(left + 1, ids.get(left)); ids[left + 1] = ids[left];
break; break;
default: default:
System.arraycopy(positions, left, positions, left + 1, n); System.arraycopy(positions, left, positions, left + 1, n);
System.arraycopy(sortKey, left, sortKey, left + 1, n); System.arraycopy(sortKey, left, sortKey, left + 1, n);
System.arraycopy(mimeTypes, left, mimeTypes, left + 1, n); System.arraycopy(mimeTypes, left, mimeTypes, left + 1, n);
for (int i = n; i >= 1; --i) { System.arraycopy(ids, left, ids, left + 1, n);
ids.set(left + i, ids.get(left + i - 1));
}
} }
positions[left] = pivotPosition; positions[left] = pivotPosition;
sortKey[left] = pivotValue; sortKey[left] = pivotValue;
mimeTypes[left] = pivotMime; mimeTypes[left] = pivotMime;
ids.set(left, pivotId); ids[left] = pivotId;
} }
} }
@@ -413,7 +409,7 @@ public class Model {
* @return An ordered array of model IDs representing the documents in the model. It is sorted * @return An ordered array of model IDs representing the documents in the model. It is sorted
* according to the current sort order, which was set by the last model update. * according to the current sort order, which was set by the last model update.
*/ */
public List<String> getModelIds() { public String[] getModelIds() {
return mIds; return mIds;
} }
} }

View File

@@ -140,8 +140,8 @@ final class ModelBackedDocumentsAdapter extends DocumentsAdapter {
Log.d(TAG, "Updating model with hidden ids: " + mHiddenIds); Log.d(TAG, "Updating model with hidden ids: " + mHiddenIds);
} }
List<String> modelIds = model.getModelIds(); String[] modelIds = model.getModelIds();
mModelIds = new ArrayList<>(modelIds.size()); mModelIds = new ArrayList<>(modelIds.length);
for (String id : modelIds) { for (String id : modelIds) {
if (!mHiddenIds.contains(id)) { if (!mHiddenIds.contains(id)) {
mModelIds.add(id); mModelIds.add(id);

View File

@@ -68,8 +68,8 @@ public class ModelBackedDocumentsAdapterTest extends AndroidTestCase {
// Tests that the item count is correct. // Tests that the item count is correct.
public void testHide_ItemCount() { public void testHide_ItemCount() {
List<String> ids = mModel.getModelIds(); String[] ids = mModel.getModelIds();
mAdapter.hide(ids.get(0), ids.get(1)); mAdapter.hide(ids[0], ids[1]);
assertEquals(mModel.getItemCount() - 2, mAdapter.getItemCount()); assertEquals(mModel.getItemCount() - 2, mAdapter.getItemCount());
} }

View File

@@ -107,7 +107,7 @@ public class ModelTest extends AndroidTestCase {
assertTrue(model.isEmpty()); assertTrue(model.isEmpty());
assertEquals(0, model.getItemCount()); assertEquals(0, model.getItemCount());
assertEquals(0, model.getModelIds().size()); assertEquals(0, model.getModelIds().length);
} }
// Tests that the item count is correct. // Tests that the item count is correct.
@@ -165,10 +165,10 @@ public class ModelTest extends AndroidTestCase {
// Tests the base case for Model.getItem. // Tests the base case for Model.getItem.
public void testGetItem() { public void testGetItem() {
List<String> ids = model.getModelIds(); String[] ids = model.getModelIds();
assertEquals(ITEM_COUNT, ids.size()); assertEquals(ITEM_COUNT, ids.length);
for (int i = 0; i < ITEM_COUNT; ++i) { for (int i = 0; i < ITEM_COUNT; ++i) {
Cursor c = model.getItem(ids.get(i)); Cursor c = model.getItem(ids[i]);
assertEquals(i, c.getPosition()); assertEquals(i, c.getPosition());
} }
} }
@@ -292,14 +292,14 @@ public class ModelTest extends AndroidTestCase {
r.sortOrder = State.SORT_ORDER_LAST_MODIFIED; r.sortOrder = State.SORT_ORDER_LAST_MODIFIED;
model.update(r); model.update(r);
List<String> ids = model.getModelIds(); String[] ids = model.getModelIds();
// Check that all items were accounted for // Check that all items were accounted for
assertEquals(ITEM_COUNT + DL_COUNT, ids.size()); assertEquals(ITEM_COUNT + DL_COUNT, ids.length);
// Check that active downloads are sorted to the top. // Check that active downloads are sorted to the top.
for (int i = 0; i < DL_COUNT; i++) { for (int i = 0; i < DL_COUNT; i++) {
assertTrue(currentDownloads.contains(ids.get(i))); assertTrue(currentDownloads.contains(ids[i]));
} }
} }
@@ -316,11 +316,11 @@ public class ModelTest extends AndroidTestCase {
} }
private Selection positionToSelection(int... positions) { private Selection positionToSelection(int... positions) {
List<String> ids = model.getModelIds(); String[] ids = model.getModelIds();
Selection s = new Selection(); Selection s = new Selection();
// Construct a selection of the given positions. // Construct a selection of the given positions.
for (int p: positions) { for (int p: positions) {
s.add(ids.get(p)); s.add(ids[p]);
} }
return s; return s;
} }