mirror of
https://github.com/AntennaPod/AntennaPod.git
synced 2024-12-24 16:02:13 +01:00
Small database efficiency tweaks (#7058)
- When checking whether there is a subscription, there is no need to create feed objects (plus counters etc). Just the number of episodes is enough. - Downloads section only needs to load the items it actually displays. - No need to load FeedMedia, just to load FeedItem including the same FeedMedia afterwards. - No need to convert columns to Strings and back to Longs. - No need to join favorites when we are only interested in the list of IDs anyway.
This commit is contained in:
parent
e894ff1ccb
commit
0288d4e51e
@ -19,6 +19,7 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentContainerView;
|
||||
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import de.danoeh.antennapod.ui.screen.home.sections.AllowNotificationsSection;
|
||||
@ -44,7 +45,6 @@ import de.danoeh.antennapod.databinding.HomeFragmentBinding;
|
||||
import de.danoeh.antennapod.event.FeedListUpdateEvent;
|
||||
import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
|
||||
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
@ -193,14 +193,12 @@ public class HomeFragment extends Fragment implements Toolbar.OnMenuItemClickLis
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
disposable = Observable.fromCallable(() ->
|
||||
DBReader.getNavDrawerData(UserPreferences.getSubscriptionsFilter(),
|
||||
UserPreferences.getFeedOrder(), UserPreferences.getFeedCounterSetting()).items.size())
|
||||
disposable = Observable.fromCallable(() -> DBReader.getTotalEpisodeCount(FeedItemFilter.unfiltered()))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(numSubscriptions -> {
|
||||
viewBinding.welcomeContainer.setVisibility(numSubscriptions == 0 ? View.VISIBLE : View.GONE);
|
||||
viewBinding.homeContainer.setVisibility(numSubscriptions == 0 ? View.GONE : View.VISIBLE);
|
||||
.subscribe(numEpisodes -> {
|
||||
viewBinding.welcomeContainer.setVisibility(numEpisodes == 0 ? View.VISIBLE : View.GONE);
|
||||
viewBinding.homeContainer.setVisibility(numEpisodes == 0 ? View.GONE : View.VISIBLE);
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
|
||||
|
@ -124,14 +124,11 @@ public class DownloadsSection extends HomeSection {
|
||||
disposable.dispose();
|
||||
}
|
||||
SortOrder sortOrder = UserPreferences.getDownloadsSortedOrder();
|
||||
disposable = Observable.fromCallable(() -> DBReader.getEpisodes(0, Integer.MAX_VALUE,
|
||||
disposable = Observable.fromCallable(() -> DBReader.getEpisodes(0, NUM_EPISODES,
|
||||
new FeedItemFilter(FeedItemFilter.DOWNLOADED), sortOrder))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(downloads -> {
|
||||
if (downloads.size() > NUM_EPISODES) {
|
||||
downloads = downloads.subList(0, NUM_EPISODES);
|
||||
}
|
||||
items = downloads;
|
||||
adapter.setDummyViews(0);
|
||||
adapter.updateItems(items);
|
||||
|
@ -246,7 +246,7 @@ public class DbWriterTest {
|
||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
|
||||
c = adapter.getFeedItemFromMediaIdCursor(item.getMedia().getId());
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
}
|
||||
@ -370,7 +370,7 @@ public class DbWriterTest {
|
||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
|
||||
c = adapter.getFeedItemFromMediaIdCursor(item.getMedia().getId());
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
}
|
||||
@ -422,7 +422,7 @@ public class DbWriterTest {
|
||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
|
||||
c = adapter.getFeedItemFromMediaIdCursor(item.getMedia().getId());
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import de.danoeh.antennapod.storage.database.mapper.ChapterCursor;
|
||||
import de.danoeh.antennapod.storage.database.mapper.DownloadResultCursor;
|
||||
import de.danoeh.antennapod.storage.database.mapper.FeedCursor;
|
||||
import de.danoeh.antennapod.storage.database.mapper.FeedItemCursor;
|
||||
import de.danoeh.antennapod.storage.database.mapper.FeedMediaCursor;
|
||||
|
||||
/**
|
||||
* Provides methods for reading data from the AntennaPod database.
|
||||
@ -223,7 +222,7 @@ public final class DBReader {
|
||||
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
try (Cursor cursor = adapter.getFavoritesIdsCursor(0, Integer.MAX_VALUE)) {
|
||||
try (Cursor cursor = adapter.getFavoritesIdsCursor()) {
|
||||
LongList favoriteIDs = new LongList(cursor.getCount());
|
||||
while (cursor.moveToNext()) {
|
||||
favoriteIDs.add(cursor.getLong(0));
|
||||
@ -511,20 +510,13 @@ public final class DBReader {
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
|
||||
try (FeedMediaCursor mediaCursor = new FeedMediaCursor(adapter.getSingleFeedMediaCursor(mediaId))) {
|
||||
if (!mediaCursor.moveToFirst()) {
|
||||
try (FeedItemCursor itemCursor = new FeedItemCursor(adapter.getFeedItemFromMediaIdCursor(mediaId))) {
|
||||
if (!itemCursor.moveToFirst()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int indexFeedItem = mediaCursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM);
|
||||
long itemId = mediaCursor.getLong(indexFeedItem);
|
||||
FeedMedia media = mediaCursor.getFeedMedia();
|
||||
FeedItem item = getFeedItem(itemId);
|
||||
if (item != null) {
|
||||
media.setItem(item);
|
||||
item.setMedia(media);
|
||||
}
|
||||
return media;
|
||||
FeedItem item = itemCursor.getFeedItem();
|
||||
loadAdditionalFeedItemListData(Collections.singletonList(item));
|
||||
return item.getMedia();
|
||||
} finally {
|
||||
adapter.close();
|
||||
}
|
||||
@ -623,13 +615,13 @@ public final class DBReader {
|
||||
while (cursor.moveToNext()) {
|
||||
Feed feed = cursor.getFeed();
|
||||
|
||||
long feedPlayedTime = Long.parseLong(cursor.getString(indexPlayedTime)) / 1000;
|
||||
long feedTotalTime = Long.parseLong(cursor.getString(indexTotalTime)) / 1000;
|
||||
long episodes = Long.parseLong(cursor.getString(indexNumEpisodes));
|
||||
long episodesStarted = Long.parseLong(cursor.getString(indexEpisodesStarted));
|
||||
long totalDownloadSize = Long.parseLong(cursor.getString(indexDownloadSize));
|
||||
long episodesDownloadCount = Long.parseLong(cursor.getString(indexNumDownloaded));
|
||||
long oldestDate = Long.parseLong(cursor.getString(indexOldestDate));
|
||||
long feedPlayedTime = cursor.getLong(indexPlayedTime) / 1000;
|
||||
long feedTotalTime = cursor.getLong(indexTotalTime) / 1000;
|
||||
long episodes = cursor.getLong(indexNumEpisodes);
|
||||
long episodesStarted = cursor.getLong(indexEpisodesStarted);
|
||||
long totalDownloadSize = cursor.getLong(indexDownloadSize);
|
||||
long episodesDownloadCount = cursor.getLong(indexNumDownloaded);
|
||||
long oldestDate = cursor.getLong(indexOldestDate);
|
||||
|
||||
if (episodes > 0 && oldestDate < Long.MAX_VALUE) {
|
||||
result.oldestDate = Math.min(result.oldestDate, oldestDate);
|
||||
@ -648,7 +640,7 @@ public final class DBReader {
|
||||
adapter.open();
|
||||
try (Cursor cursor = adapter.getTimeBetweenReleaseAndPlayback(timeFilterFrom, timeFilterTo)) {
|
||||
cursor.moveToFirst();
|
||||
long result = Long.parseLong(cursor.getString(0));
|
||||
long result = cursor.getLong(0);
|
||||
adapter.close();
|
||||
return result;
|
||||
}
|
||||
|
@ -1043,14 +1043,9 @@ public class PodDBAdapter {
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
public final Cursor getFavoritesIdsCursor(int offset, int limit) {
|
||||
// Way faster than selecting all columns
|
||||
final String query = "SELECT " + TABLE_NAME_FEED_ITEMS + "." + KEY_ID
|
||||
+ " FROM " + TABLE_NAME_FEED_ITEMS
|
||||
+ " INNER JOIN " + TABLE_NAME_FAVORITES
|
||||
+ " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + " = " + TABLE_NAME_FAVORITES + "." + KEY_FEEDITEM
|
||||
+ " ORDER BY " + TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC"
|
||||
+ " LIMIT " + offset + ", " + limit;
|
||||
public final Cursor getFavoritesIdsCursor() {
|
||||
final String query = "SELECT " + TABLE_NAME_FAVORITES + "." + KEY_FEEDITEM
|
||||
+ " FROM " + TABLE_NAME_FAVORITES;
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
@ -1109,9 +1104,9 @@ public class PodDBAdapter {
|
||||
return "((" + SELECT_KEY_ITEM_ID + " * " + seed + ") % 46471)";
|
||||
}
|
||||
|
||||
public final Cursor getSingleFeedMediaCursor(long id) {
|
||||
final String query = "SELECT " + KEYS_FEED_MEDIA + " FROM " + TABLE_NAME_FEED_MEDIA
|
||||
+ " WHERE " + KEY_ID + "=" + id;
|
||||
public final Cursor getFeedItemFromMediaIdCursor(long mediaId) {
|
||||
final String query = SELECT_FEED_ITEMS_AND_MEDIA
|
||||
+ " WHERE " + SELECT_KEY_MEDIA_ID + " = " + mediaId;
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user