From 5f0ecb5d596b1dc64701ba2b616e42e1e43f0195 Mon Sep 17 00:00:00 2001 From: Martin Fietz Date: Wed, 2 Dec 2015 12:34:01 +0100 Subject: [PATCH] Use MergeCursor for high number of images --- .../antennapod/core/storage/DBReader.java | 18 +++++---- .../antennapod/core/storage/PodDBAdapter.java | 40 +++++++++++++++---- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java index c0a30f740..c34515118 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java @@ -225,12 +225,12 @@ public final class DBReader { private static Map getFeedMedia(PodDBAdapter adapter, long... itemIds) { - ArrayList ids = new ArrayList<>(itemIds.length); - for(long itemId : itemIds) { - ids.add(String.valueOf(itemId)); + String[] ids = new String[itemIds.length]; + for(int i=0, len=itemIds.length; i < len; i++) { + ids[i] = String.valueOf(itemIds[i]); } Map result = new HashMap<>(itemIds.length); - Cursor cursor = adapter.getFeedMediaCursor(ids.toArray(new String[0])); + Cursor cursor = adapter.getFeedMediaCursor(ids); try { if (cursor.moveToFirst()) { do { @@ -862,10 +862,14 @@ public final class DBReader { /** * Searches the DB for a FeedImage of the given id. * - * @param ids The id of the object - * @return The found object + * @param imageIds The ids of the images + * @return Map that associates the id of an image with the image itself */ - private static Map getFeedImages(PodDBAdapter adapter, final long... ids) { + private static Map 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); Map result = new HashMap<>(cursor.getCount()); try { diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index bf324c9d1..05af9303f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -14,7 +14,6 @@ import android.os.Build; import android.text.TextUtils; import android.util.Log; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; 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. * - * @param ids IDs of the FeedImages + * @param imageIds IDs of the images * @return The cursor of the query */ - public final Cursor getImageCursor(long... ids) { - String sql = "SELECT * FROM " + TABLE_NAME_FEED_IMAGES + - " WHERE " + KEY_ID + " IN (" + StringUtils.join(ids, ',') + ")"; - Cursor c = db.rawQuery(sql, null); + public final Cursor getImageCursor(String... imageIds) { + int length = imageIds.length; + if (length > IN_OPERATOR_MAXIMUM) { + 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) {