1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-27 19:52:17 -05:00

Switch MergeCursor from using a List to an array

This commit is contained in:
cketti 2012-10-25 23:14:28 +02:00
parent 49a5a3b7ff
commit 08fba5468f
3 changed files with 114 additions and 96 deletions

View File

@ -338,7 +338,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
private String[] mAccountUuids; private String[] mAccountUuids;
private int mUnreadMessageCount = 0; private int mUnreadMessageCount = 0;
private Map<Integer, Cursor> mCursors = new HashMap<Integer, Cursor>(); private Cursor[] mCursors;
/** /**
* Stores the name of the folder that we want to open as soon as possible * Stores the name of the folder that we want to open as soon as possible
@ -700,7 +700,9 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
initializeMessageList(); initializeMessageList();
LoaderManager loaderManager = getLoaderManager(); LoaderManager loaderManager = getLoaderManager();
for (int i = 0, len = mAccountUuids.length; i < len; i++) { int len = mAccountUuids.length;
mCursors = new Cursor[len];
for (int i = 0; i < len; i++) {
loaderManager.initLoader(i, null, this); loaderManager.initLoader(i, null, this);
} }
} }
@ -2757,16 +2759,9 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
@Override @Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mCursors.put(loader.getId(), data); mCursors[loader.getId()] = data;
List<Integer> list = new LinkedList<Integer>(mCursors.keySet()); MergeCursorWithUniqueId cursor = new MergeCursorWithUniqueId(mCursors);
Collections.sort(list);
List<Cursor> cursors = new ArrayList<Cursor>(list.size());
for (Integer id : list) {
cursors.add(mCursors.get(id));
}
MergeCursorWithUniqueId cursor = new MergeCursorWithUniqueId(cursors);
mSelected = new SparseBooleanArray(cursor.getCount()); mSelected = new SparseBooleanArray(cursor.getCount());
//TODO: use the (stable) IDs as index and reuse the old mSelected //TODO: use the (stable) IDs as index and reuse the old mSelected

View File

@ -1,7 +1,23 @@
/*
* Copyright (C) 2012 The K-9 Dog Walkers
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fsck.k9.helper; package com.fsck.k9.helper;
import java.util.List; import android.annotation.TargetApi;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.database.CharArrayBuffer; import android.database.CharArrayBuffer;
import android.database.ContentObserver; import android.database.ContentObserver;
@ -18,7 +34,7 @@ public class MergeCursor implements Cursor {
/** /**
* List of the cursors combined in this object. * List of the cursors combined in this object.
*/ */
protected final List<Cursor> mCursors; protected final Cursor[] mCursors;
/** /**
* The currently active cursor. * The currently active cursor.
@ -32,6 +48,8 @@ public class MergeCursor implements Cursor {
*/ */
protected int mActiveCursorIndex; protected int mActiveCursorIndex;
protected int mPosition;
/** /**
* Used to cache the value of {@link #getCount()} * Used to cache the value of {@link #getCount()}
*/ */
@ -44,18 +62,26 @@ public class MergeCursor implements Cursor {
* @param cursors * @param cursors
* The list of cursors this {@code MultiCursor} should combine. * The list of cursors this {@code MultiCursor} should combine.
*/ */
public MergeCursor(List<Cursor> cursors) { public MergeCursor(Cursor[] cursors) {
mCursors = cursors; mCursors = cursors.clone();
mActiveCursorIndex = 0;
mActiveCursor = cursors.get(0); for (int i = 0, len = mCursors.length; i < len; i++) {
if (mCursors[i] != null) {
mActiveCursorIndex = i;
mActiveCursor = mCursors[mActiveCursorIndex];
}
}
mPosition = -1;
} }
@Override @Override
public void close() { public void close() {
for (Cursor cursor : mCursors) { for (Cursor cursor : mCursors) {
if (cursor != null) {
cursor.close(); cursor.close();
} }
} }
}
@Override @Override
public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
@ -65,9 +91,11 @@ public class MergeCursor implements Cursor {
@Override @Override
public void deactivate() { public void deactivate() {
for (Cursor cursor : mCursors) { for (Cursor cursor : mCursors) {
if (cursor != null) {
cursor.deactivate(); cursor.deactivate();
} }
} }
}
@Override @Override
public byte[] getBlob(int columnIndex) { public byte[] getBlob(int columnIndex) {
@ -105,8 +133,10 @@ public class MergeCursor implements Cursor {
if (mCount == -1) { if (mCount == -1) {
int count = 0; int count = 0;
for (Cursor cursor : mCursors) { for (Cursor cursor : mCursors) {
if (cursor != null) {
count += cursor.getCount(); count += cursor.getCount();
} }
}
mCount = count; mCount = count;
} }
@ -136,12 +166,7 @@ public class MergeCursor implements Cursor {
@Override @Override
public int getPosition() { public int getPosition() {
int pos = 0; return mPosition;
for (int i = 0; i < mActiveCursorIndex; i++) {
pos += mCursors.get(i).getCount();
}
return pos + mActiveCursor.getPosition();
} }
@Override @Override
@ -154,6 +179,7 @@ public class MergeCursor implements Cursor {
return mActiveCursor.getString(columnIndex); return mActiveCursor.getString(columnIndex);
} }
@TargetApi(11)
@Override @Override
public int getType(int columnIndex) { public int getType(int columnIndex) {
return mActiveCursor.getType(columnIndex); return mActiveCursor.getType(columnIndex);
@ -166,20 +192,21 @@ public class MergeCursor implements Cursor {
@Override @Override
public boolean isAfterLast() { public boolean isAfterLast() {
if (mActiveCursorIndex == mCursors.size() - 1) { int count = getCount();
return mActiveCursor.isAfterLast(); if (count == 0) {
return true;
} }
return false; return (mPosition == count);
} }
@Override @Override
public boolean isBeforeFirst() { public boolean isBeforeFirst() {
if (mActiveCursorIndex == 0) { if (getCount() == 0) {
return mActiveCursor.isBeforeFirst(); return true;
} }
return false; return (mPosition == -1);
} }
@Override @Override
@ -189,20 +216,21 @@ public class MergeCursor implements Cursor {
@Override @Override
public boolean isFirst() { public boolean isFirst() {
if (mActiveCursorIndex == 0) { if (getCount() == 0) {
return mActiveCursor.isFirst(); return false;
} }
return false; return (mPosition == 0);
} }
@Override @Override
public boolean isLast() { public boolean isLast() {
if (mActiveCursorIndex == mCursors.size() - 1) { int count = getCount();
return mActiveCursor.isLast(); if (count == 0) {
return false;
} }
return false; return (mPosition == (count - 1));
} }
@Override @Override
@ -212,81 +240,78 @@ public class MergeCursor implements Cursor {
@Override @Override
public boolean move(int offset) { public boolean move(int offset) {
int ofs = offset; return moveToPosition(mPosition + offset);
int pos = mActiveCursor.getPosition();
if (offset >= 0) {
while (pos + ofs > mActiveCursor.getCount() &
mActiveCursorIndex < mCursors.size() - 1) {
// Adjust the "move offset"
ofs -= mActiveCursor.getCount() - pos;
// Move to the next cursor
mActiveCursor = mCursors.get(++mActiveCursorIndex);
// Move the new cursor to the first position
mActiveCursor.moveToFirst();
pos = 0;
}
} else {
while (pos + ofs < 0 && mActiveCursorIndex > 0) {
// Adjust the "move offset"
ofs += pos;
// Move to the next cursor
mActiveCursor = mCursors.get(--mActiveCursorIndex);
// Move the new cursor to the first position
mActiveCursor.moveToLast();
pos = mActiveCursor.getPosition();
}
}
return mActiveCursor.move(ofs);
} }
@Override @Override
public boolean moveToFirst() { public boolean moveToFirst() {
mActiveCursorIndex = 0; return moveToPosition(0);
mActiveCursor = mCursors.get(mActiveCursorIndex);
return mActiveCursor.moveToFirst();
} }
@Override @Override
public boolean moveToLast() { public boolean moveToLast() {
mActiveCursorIndex = mCursors.size() - 1; return moveToPosition(getCount() - 1);
mActiveCursor = mCursors.get(mActiveCursorIndex);
return mActiveCursor.moveToLast();
} }
@Override @Override
public boolean moveToNext() { public boolean moveToNext() {
return move(1); return moveToPosition(mPosition + 1);
} }
@Override @Override
public boolean moveToPosition(int position) { public boolean moveToPosition(int position) {
// Start at the beginning // Make sure position isn't past the end of the cursor
mActiveCursorIndex = 0; final int count = getCount();
mActiveCursor = mCursors.get(mActiveCursorIndex); if (position >= count) {
mPosition = count;
int pos = position; return false;
while (pos > mActiveCursor.getCount() - 1 &&
mActiveCursorIndex < mCursors.size() - 1) {
// Adjust the position
pos -= mActiveCursor.getCount();
// Move to the next cursor
mActiveCursor = mCursors.get(++mActiveCursorIndex);
} }
return mActiveCursor.moveToPosition(pos); // Make sure position isn't before the beginning of the cursor
if (position < 0) {
mPosition = -1;
return false;
}
// Check for no-op moves, and skip the rest of the work for them
if (position == mPosition) {
return true;
}
/* Find the right cursor */
mActiveCursor = null;
mActiveCursorIndex = -1;
mPosition = -1;
int cursorStartPos = 0;
for (int i = 0, len = mCursors.length; i < len; i++) {
if (mCursors[i] == null) {
continue;
}
if (position < (cursorStartPos + mCursors[i].getCount())) {
mActiveCursorIndex = i;
mActiveCursor = mCursors[mActiveCursorIndex];
break;
}
cursorStartPos += mCursors[i].getCount();
}
/* Move it to the right position */
if (mActiveCursor != null) {
boolean success = mActiveCursor.moveToPosition(position - cursorStartPos);
mPosition = (success) ? position : -1;
return success;
}
return false;
} }
@Override @Override
public boolean moveToPrevious() { public boolean moveToPrevious() {
return move(-1); return moveToPosition(mPosition - 1);
} }
@Override @Override

View File

@ -1,7 +1,5 @@
package com.fsck.k9.helper; package com.fsck.k9.helper;
import java.util.List;
import android.database.Cursor; import android.database.Cursor;
@ -14,10 +12,10 @@ public class MergeCursorWithUniqueId extends MergeCursor {
private int mIdColumnIndex = -1; private int mIdColumnIndex = -1;
public MergeCursorWithUniqueId(List<Cursor> cursors) { public MergeCursorWithUniqueId(Cursor[] cursors) {
super(cursors); super(cursors);
if (cursors.size() > MAX_CURSORS) { if (cursors.length > MAX_CURSORS) {
throw new IllegalArgumentException("This class only supports up to " + throw new IllegalArgumentException("This class only supports up to " +
MAX_CURSORS + " cursors"); MAX_CURSORS + " cursors");
} }