Use MergeCursor for high number of images

This commit is contained in:
Martin Fietz 2015-12-02 12:34:01 +01:00
parent a777d7739e
commit 5f0ecb5d59
2 changed files with 44 additions and 14 deletions

View File

@ -225,12 +225,12 @@ public final class DBReader {
private static Map<Long,FeedMedia> getFeedMedia(PodDBAdapter adapter, private static Map<Long,FeedMedia> getFeedMedia(PodDBAdapter adapter,
long... itemIds) { long... itemIds) {
ArrayList<String> ids = new ArrayList<>(itemIds.length); String[] ids = new String[itemIds.length];
for(long itemId : itemIds) { for(int i=0, len=itemIds.length; i < len; i++) {
ids.add(String.valueOf(itemId)); ids[i] = String.valueOf(itemIds[i]);
} }
Map<Long,FeedMedia> result = new HashMap<>(itemIds.length); Map<Long,FeedMedia> result = new HashMap<>(itemIds.length);
Cursor cursor = adapter.getFeedMediaCursor(ids.toArray(new String[0])); Cursor cursor = adapter.getFeedMediaCursor(ids);
try { try {
if (cursor.moveToFirst()) { if (cursor.moveToFirst()) {
do { do {
@ -862,10 +862,14 @@ public final class DBReader {
/** /**
* Searches the DB for a FeedImage of the given id. * Searches the DB for a FeedImage of the given id.
* *
* @param ids The id of the object * @param imageIds The ids of the images
* @return The found object * @return Map that associates the id of an image with the image itself
*/ */
private static Map<Long,FeedImage> getFeedImages(PodDBAdapter adapter, final long... ids) { private static Map<Long,FeedImage> getFeedImages(PodDBAdapter adapter, final long... imageIds) {
String[] ids = new String[imageIds.length];
for(int i=0, len=imageIds.length; i < len; i++) {
ids[i] = String.valueOf(imageIds[i]);
}
Cursor cursor = adapter.getImageCursor(ids); Cursor cursor = adapter.getImageCursor(ids);
Map<Long, FeedImage> result = new HashMap<>(cursor.getCount()); Map<Long, FeedImage> result = new HashMap<>(cursor.getCount());
try { try {

View File

@ -14,7 +14,6 @@ import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import java.util.Arrays; import java.util.Arrays;
@ -1018,15 +1017,42 @@ public class PodDBAdapter {
/** /**
* Returns a cursor for a DB query in the FeedImages table for given IDs. * Returns a cursor for a DB query in the FeedImages table for given IDs.
* *
* @param ids IDs of the FeedImages * @param imageIds IDs of the images
* @return The cursor of the query * @return The cursor of the query
*/ */
public final Cursor getImageCursor(long... ids) { public final Cursor getImageCursor(String... imageIds) {
String sql = "SELECT * FROM " + TABLE_NAME_FEED_IMAGES + int length = imageIds.length;
" WHERE " + KEY_ID + " IN (" + StringUtils.join(ids, ',') + ")"; if (length > IN_OPERATOR_MAXIMUM) {
Cursor c = db.rawQuery(sql, null); Log.w(TAG, "Length of id array is larger than "
+ IN_OPERATOR_MAXIMUM + ". Creating multiple cursors");
int numCursors = (int) (((double) length) / (IN_OPERATOR_MAXIMUM)) + 1;
Cursor[] cursors = new Cursor[numCursors];
for (int i = 0; i < numCursors; i++) {
int neededLength;
String[] parts;
final int elementsLeft = length - i * IN_OPERATOR_MAXIMUM;
return c; if (elementsLeft >= IN_OPERATOR_MAXIMUM) {
neededLength = IN_OPERATOR_MAXIMUM;
parts = Arrays.copyOfRange(imageIds, i
* IN_OPERATOR_MAXIMUM, (i + 1)
* IN_OPERATOR_MAXIMUM);
} else {
neededLength = elementsLeft;
parts = Arrays.copyOfRange(imageIds, i
* IN_OPERATOR_MAXIMUM, (i * IN_OPERATOR_MAXIMUM)
+ neededLength);
}
cursors[i] = db.rawQuery("SELECT * FROM "
+ TABLE_NAME_FEED_IMAGES + " WHERE " + KEY_ID + " IN "
+ buildInOperator(neededLength), parts);
}
return new MergeCursor(cursors);
} else {
return db.query(TABLE_NAME_FEED_IMAGES, null, KEY_ID + " IN "
+ buildInOperator(length), imageIds, null, null, null);
}
} }
public final Cursor getSimpleChaptersOfFeedItemCursor(final FeedItem item) { public final Cursor getSimpleChaptersOfFeedItemCursor(final FeedItem item) {