Merge pull request #4891 from vkay94/locallist-entry-progressTime

Improve performance for some updateState calls (local lists)
This commit is contained in:
Stypox 2020-11-20 17:12:16 +01:00 committed by GitHub
commit 72177033d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 36 deletions

View File

@ -20,6 +20,9 @@ import static org.schabi.newpipe.database.stream.StreamStatisticsEntry.STREAM_LA
import static org.schabi.newpipe.database.stream.StreamStatisticsEntry.STREAM_WATCH_COUNT; import static org.schabi.newpipe.database.stream.StreamStatisticsEntry.STREAM_WATCH_COUNT;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID_ALIAS;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_TIME;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE;
@Dao @Dao
public abstract class StreamHistoryDAO implements HistoryDAO<StreamHistoryEntity> { public abstract class StreamHistoryDAO implements HistoryDAO<StreamHistoryEntity> {
@ -73,6 +76,12 @@ public abstract class StreamHistoryDAO implements HistoryDAO<StreamHistoryEntity
+ " SUM(" + STREAM_REPEAT_COUNT + ") AS " + STREAM_WATCH_COUNT + " SUM(" + STREAM_REPEAT_COUNT + ") AS " + STREAM_WATCH_COUNT
+ " FROM " + STREAM_HISTORY_TABLE + " GROUP BY " + JOIN_STREAM_ID + ")" + " FROM " + STREAM_HISTORY_TABLE + " GROUP BY " + JOIN_STREAM_ID + ")"
+ " ON " + STREAM_ID + " = " + JOIN_STREAM_ID) + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID
+ " LEFT JOIN "
+ "(SELECT " + JOIN_STREAM_ID + " AS " + JOIN_STREAM_ID_ALIAS + ", "
+ STREAM_PROGRESS_TIME
+ " FROM " + STREAM_STATE_TABLE + " )"
+ " ON " + STREAM_ID + " = " + JOIN_STREAM_ID_ALIAS)
public abstract Flowable<List<StreamStatisticsEntry>> getStatistics(); public abstract Flowable<List<StreamStatisticsEntry>> getStatistics();
} }

View File

@ -5,12 +5,16 @@ import androidx.room.Embedded
import org.schabi.newpipe.database.LocalItem import org.schabi.newpipe.database.LocalItem
import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity
import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.stream.model.StreamStateEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamInfoItem
class PlaylistStreamEntry( class PlaylistStreamEntry(
@Embedded @Embedded
val streamEntity: StreamEntity, val streamEntity: StreamEntity,
@ColumnInfo(name = StreamStateEntity.STREAM_PROGRESS_TIME, defaultValue = "0")
val progressTime: Long,
@ColumnInfo(name = PlaylistStreamEntity.JOIN_STREAM_ID) @ColumnInfo(name = PlaylistStreamEntity.JOIN_STREAM_ID)
val streamId: Long, val streamId: Long,

View File

@ -24,6 +24,9 @@ import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.JO
import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.PLAYLIST_STREAM_JOIN_TABLE; import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.PLAYLIST_STREAM_JOIN_TABLE;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID_ALIAS;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_TIME;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE;
@Dao @Dao
public abstract class PlaylistStreamDAO implements BasicDAO<PlaylistStreamEntity> { public abstract class PlaylistStreamDAO implements BasicDAO<PlaylistStreamEntity> {
@ -58,6 +61,13 @@ public abstract class PlaylistStreamDAO implements BasicDAO<PlaylistStreamEntity
// then merge with the stream metadata // then merge with the stream metadata
+ " ON " + STREAM_ID + " = " + JOIN_STREAM_ID + " ON " + STREAM_ID + " = " + JOIN_STREAM_ID
+ " LEFT JOIN "
+ "(SELECT " + JOIN_STREAM_ID + " AS " + JOIN_STREAM_ID_ALIAS + ", "
+ STREAM_PROGRESS_TIME
+ " FROM " + STREAM_STATE_TABLE + " )"
+ " ON " + STREAM_ID + " = " + JOIN_STREAM_ID_ALIAS
+ " ORDER BY " + JOIN_INDEX + " ASC") + " ORDER BY " + JOIN_INDEX + " ASC")
public abstract Flowable<List<PlaylistStreamEntry>> getOrderedStreamsOf(long playlistId); public abstract Flowable<List<PlaylistStreamEntry>> getOrderedStreamsOf(long playlistId);

View File

@ -2,23 +2,27 @@ package org.schabi.newpipe.database.stream
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Embedded import androidx.room.Embedded
import java.time.OffsetDateTime
import org.schabi.newpipe.database.LocalItem import org.schabi.newpipe.database.LocalItem
import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.history.model.StreamHistoryEntity
import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_TIME
import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamInfoItem
import java.time.OffsetDateTime
class StreamStatisticsEntry( class StreamStatisticsEntry(
@Embedded @Embedded
val streamEntity: StreamEntity, val streamEntity: StreamEntity,
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID) @ColumnInfo(name = STREAM_PROGRESS_TIME, defaultValue = "0")
val progressTime: Long,
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
val streamId: Long, val streamId: Long,
@ColumnInfo(name = STREAM_LATEST_DATE) @ColumnInfo(name = STREAM_LATEST_DATE)
val latestAccessDate: OffsetDateTime, val latestAccessDate: OffsetDateTime,
@ColumnInfo(name = STREAM_WATCH_COUNT) @ColumnInfo(name = STREAM_WATCH_COUNT)
val watchCount: Long val watchCount: Long
) : LocalItem { ) : LocalItem {
fun toStreamInfoItem(): StreamInfoItem { fun toStreamInfoItem(): StreamInfoItem {

View File

@ -22,6 +22,9 @@ import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_
public class StreamStateEntity { public class StreamStateEntity {
public static final String STREAM_STATE_TABLE = "stream_state"; public static final String STREAM_STATE_TABLE = "stream_state";
public static final String JOIN_STREAM_ID = "stream_id"; public static final String JOIN_STREAM_ID = "stream_id";
// This additional field is required for the SQL query because 'stream_id' is used
// for some other joins already
public static final String JOIN_STREAM_ID_ALIAS = "stream_id_alias";
public static final String STREAM_PROGRESS_TIME = "progress_time"; public static final String STREAM_PROGRESS_TIME = "progress_time";
/** /**

View File

@ -11,7 +11,6 @@ import androidx.core.content.ContextCompat;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem; import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.history.HistoryRecordManager;
@ -21,7 +20,6 @@ import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.views.AnimatedProgressBar; import org.schabi.newpipe.views.AnimatedProgressBar;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class LocalPlaylistStreamItemHolder extends LocalItemHolder { public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
@ -70,15 +68,11 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
R.color.duration_background_color)); R.color.duration_background_color));
itemDurationView.setVisibility(View.VISIBLE); itemDurationView.setVisibility(View.VISIBLE);
final StreamStateEntity state = historyRecordManager if (item.getProgressTime() > 0) {
.loadLocalStreamStateBatch(new ArrayList<LocalItem>() {{
add(localItem);
}}).blockingGet().get(0);
if (state != null) {
itemProgressView.setVisibility(View.VISIBLE); itemProgressView.setVisibility(View.VISIBLE);
itemProgressView.setMax((int) item.getStreamEntity().getDuration()); itemProgressView.setMax((int) item.getStreamEntity().getDuration());
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
.toSeconds(state.getProgressTime())); .toSeconds(item.getProgressTime()));
} else { } else {
itemProgressView.setVisibility(View.GONE); itemProgressView.setVisibility(View.GONE);
} }
@ -115,18 +109,14 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
} }
final PlaylistStreamEntry item = (PlaylistStreamEntry) localItem; final PlaylistStreamEntry item = (PlaylistStreamEntry) localItem;
final StreamStateEntity state = historyRecordManager if (item.getProgressTime() > 0 && item.getStreamEntity().getDuration() > 0) {
.loadLocalStreamStateBatch(new ArrayList<LocalItem>() {{
add(localItem);
}}).blockingGet().get(0);
if (state != null && item.getStreamEntity().getDuration() > 0) {
itemProgressView.setMax((int) item.getStreamEntity().getDuration()); itemProgressView.setMax((int) item.getStreamEntity().getDuration());
if (itemProgressView.getVisibility() == View.VISIBLE) { if (itemProgressView.getVisibility() == View.VISIBLE) {
itemProgressView.setProgressAnimated((int) TimeUnit.MILLISECONDS itemProgressView.setProgressAnimated((int) TimeUnit.MILLISECONDS
.toSeconds(state.getProgressTime())); .toSeconds(item.getProgressTime()));
} else { } else {
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
.toSeconds(state.getProgressTime())); .toSeconds(item.getProgressTime()));
AnimationUtils.animateView(itemProgressView, true, 500); AnimationUtils.animateView(itemProgressView, true, 500);
} }
} else if (itemProgressView.getVisibility() == View.VISIBLE) { } else if (itemProgressView.getVisibility() == View.VISIBLE) {

View File

@ -11,7 +11,6 @@ import androidx.core.content.ContextCompat;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem; import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.stream.StreamStatisticsEntry; import org.schabi.newpipe.database.stream.StreamStatisticsEntry;
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.history.HistoryRecordManager;
@ -21,7 +20,6 @@ import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.views.AnimatedProgressBar; import org.schabi.newpipe.views.AnimatedProgressBar;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/* /*
@ -98,15 +96,11 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
R.color.duration_background_color)); R.color.duration_background_color));
itemDurationView.setVisibility(View.VISIBLE); itemDurationView.setVisibility(View.VISIBLE);
final StreamStateEntity state = historyRecordManager if (item.getProgressTime() > 0) {
.loadLocalStreamStateBatch(new ArrayList<LocalItem>() {{
add(localItem);
}}).blockingGet().get(0);
if (state != null) {
itemProgressView.setVisibility(View.VISIBLE); itemProgressView.setVisibility(View.VISIBLE);
itemProgressView.setMax((int) item.getStreamEntity().getDuration()); itemProgressView.setMax((int) item.getStreamEntity().getDuration());
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
.toSeconds(state.getProgressTime())); .toSeconds(item.getProgressTime()));
} else { } else {
itemProgressView.setVisibility(View.GONE); itemProgressView.setVisibility(View.GONE);
} }
@ -146,18 +140,14 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
} }
final StreamStatisticsEntry item = (StreamStatisticsEntry) localItem; final StreamStatisticsEntry item = (StreamStatisticsEntry) localItem;
final StreamStateEntity state = historyRecordManager if (item.getProgressTime() > 0 && item.getStreamEntity().getDuration() > 0) {
.loadLocalStreamStateBatch(new ArrayList<LocalItem>() {{
add(localItem);
}}).blockingGet().get(0);
if (state != null && item.getStreamEntity().getDuration() > 0) {
itemProgressView.setMax((int) item.getStreamEntity().getDuration()); itemProgressView.setMax((int) item.getStreamEntity().getDuration());
if (itemProgressView.getVisibility() == View.VISIBLE) { if (itemProgressView.getVisibility() == View.VISIBLE) {
itemProgressView.setProgressAnimated((int) TimeUnit.MILLISECONDS itemProgressView.setProgressAnimated((int) TimeUnit.MILLISECONDS
.toSeconds(state.getProgressTime())); .toSeconds(item.getProgressTime()));
} else { } else {
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
.toSeconds(state.getProgressTime())); .toSeconds(item.getProgressTime()));
AnimationUtils.animateView(itemProgressView, true, 500); AnimationUtils.animateView(itemProgressView, true, 500);
} }
} else if (itemProgressView.getVisibility() == View.VISIBLE) { } else if (itemProgressView.getVisibility() == View.VISIBLE) {