Use binary search to remove watched items from playlists
This commit is contained in:
parent
0ac2865b74
commit
9c3f138b8e
|
@ -49,6 +49,13 @@ public abstract class StreamHistoryDAO implements HistoryDAO<StreamHistoryEntity
|
||||||
+ " ORDER BY " + STREAM_ACCESS_DATE + " DESC")
|
+ " ORDER BY " + STREAM_ACCESS_DATE + " DESC")
|
||||||
public abstract Flowable<List<StreamHistoryEntry>> getHistory();
|
public abstract Flowable<List<StreamHistoryEntry>> getHistory();
|
||||||
|
|
||||||
|
|
||||||
|
@Query("SELECT * FROM " + STREAM_TABLE
|
||||||
|
+ " INNER JOIN " + STREAM_HISTORY_TABLE
|
||||||
|
+ " ON " + STREAM_ID + " = " + JOIN_STREAM_ID
|
||||||
|
+ " ORDER BY " + STREAM_ID + " ASC")
|
||||||
|
public abstract Flowable<List<StreamHistoryEntry>> getHistorySortedById();
|
||||||
|
|
||||||
@Query("SELECT * FROM " + STREAM_HISTORY_TABLE + " WHERE " + JOIN_STREAM_ID
|
@Query("SELECT * FROM " + STREAM_HISTORY_TABLE + " WHERE " + JOIN_STREAM_ID
|
||||||
+ " = :streamId ORDER BY " + STREAM_ACCESS_DATE + " DESC LIMIT 1")
|
+ " = :streamId ORDER BY " + STREAM_ACCESS_DATE + " DESC LIMIT 1")
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -120,6 +120,10 @@ public class HistoryRecordManager {
|
||||||
return streamHistoryTable.getHistory().subscribeOn(Schedulers.io());
|
return streamHistoryTable.getHistory().subscribeOn(Schedulers.io());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Flowable<List<StreamHistoryEntry>> getStreamHistorySortedById() {
|
||||||
|
return streamHistoryTable.getHistorySortedById().subscribeOn(Schedulers.io());
|
||||||
|
}
|
||||||
|
|
||||||
public Flowable<List<StreamStatisticsEntry>> getStreamStatistics() {
|
public Flowable<List<StreamStatisticsEntry>> getStreamStatistics() {
|
||||||
return streamHistoryTable.getStatistics().subscribeOn(Schedulers.io());
|
return streamHistoryTable.getStatistics().subscribeOn(Schedulers.io());
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,74 +375,54 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
||||||
removeWatchedDisposable = Flowable.just(playlistManager.getPlaylistStreams(playlistId).blockingFirst())
|
removeWatchedDisposable = Flowable.just(playlistManager.getPlaylistStreams(playlistId).blockingFirst())
|
||||||
.subscribeOn(Schedulers.newThread())
|
.subscribeOn(Schedulers.newThread())
|
||||||
.map((@NonNull List<PlaylistStreamEntry> playlist) -> {
|
.map((@NonNull List<PlaylistStreamEntry> playlist) -> {
|
||||||
List<PlaylistStreamEntry> localItems = new ArrayList<>();
|
|
||||||
boolean thumbnailVideoRemoved = false;
|
|
||||||
Long removedItemCount = 0l;
|
|
||||||
|
|
||||||
HistoryRecordManager recordManager = new HistoryRecordManager(getContext());
|
HistoryRecordManager recordManager = new HistoryRecordManager(getContext());
|
||||||
|
Iterator<PlaylistStreamEntry> playlistIter = playlist.iterator();
|
||||||
|
Iterator<StreamHistoryEntry> historyIter = recordManager
|
||||||
|
.getStreamHistorySortedById().blockingFirst().iterator();
|
||||||
|
|
||||||
Iterator<PlaylistStreamEntry> it_playlist = playlist.iterator();
|
// already sorted by ^ getStreamHistorySortedById(), binary search can be used
|
||||||
PlaylistStreamEntry playlist_item = null;
|
ArrayList<Long> historyStreamIds = new ArrayList<>();
|
||||||
|
while(historyIter.hasNext()) {
|
||||||
boolean isNonDuplicate;
|
historyStreamIds.add(historyIter.next().getStreamId());
|
||||||
|
|
||||||
Iterator<StreamHistoryEntry> it_history = recordManager.getStreamHistory().blockingFirst().iterator();
|
|
||||||
ArrayList<Long> history_streamIds = new ArrayList<>();
|
|
||||||
|
|
||||||
while(it_history.hasNext())
|
|
||||||
{
|
|
||||||
history_streamIds.add(it_history.next().getStreamId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(it_playlist.hasNext())
|
List<PlaylistStreamEntry> notWatchedItems = new ArrayList<>();
|
||||||
{
|
boolean thumbnailVideoRemoved = false;
|
||||||
playlist_item = it_playlist.next();
|
while(playlistIter.hasNext()) {
|
||||||
isNonDuplicate = true;
|
PlaylistStreamEntry playlistItem = playlistIter.next();
|
||||||
|
int indexInHistory = Collections.binarySearch(historyStreamIds, playlistItem.getStreamId());
|
||||||
|
|
||||||
for (long history_id : history_streamIds) {
|
if (indexInHistory < 0) {
|
||||||
if (history_id == playlist_item.getStreamId()) {
|
notWatchedItems.add(playlistItem);
|
||||||
isNonDuplicate = false;
|
} else if (!thumbnailVideoRemoved && playlistManager.getPlaylistThumbnail(playlistId).equals(playlistItem.getStreamEntity().getThumbnailUrl())) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNonDuplicate) {
|
|
||||||
localItems.add(playlist_item);
|
|
||||||
} else {
|
|
||||||
removedItemCount++;
|
|
||||||
if (!thumbnailVideoRemoved && playlistManager.getPlaylistThumbnail(playlistId).equals(playlist_item.getStreamEntity().getThumbnailUrl())) {
|
|
||||||
thumbnailVideoRemoved = true;
|
thumbnailVideoRemoved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return Flowable.just(localItems, removedItemCount, thumbnailVideoRemoved);
|
return Flowable.just(notWatchedItems, thumbnailVideoRemoved);
|
||||||
}
|
})
|
||||||
)
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(
|
.subscribe(flow -> {
|
||||||
flow -> {
|
List<PlaylistStreamEntry> notWatchedItems = (List<PlaylistStreamEntry>) flow.blockingFirst();
|
||||||
List<PlaylistStreamEntry> localItems = (List<PlaylistStreamEntry>) flow.blockingFirst();
|
boolean thumbnailVideoRemoved = (Boolean) flow.blockingLast();
|
||||||
Boolean thumbnailVideoRemoved = (Boolean) flow.blockingLast();
|
|
||||||
|
|
||||||
itemListAdapter.clearStreamItemList();
|
itemListAdapter.clearStreamItemList();
|
||||||
itemListAdapter.addItems(localItems);
|
itemListAdapter.addItems(notWatchedItems);
|
||||||
localItems.clear();
|
|
||||||
|
|
||||||
if (thumbnailVideoRemoved)
|
|
||||||
updateThumbnailUrl();
|
|
||||||
|
|
||||||
int amountOfVideos = itemListAdapter.getItemsList().size();
|
|
||||||
setVideoCount(amountOfVideos);
|
|
||||||
|
|
||||||
saveChanges();
|
saveChanges();
|
||||||
hideLoading();
|
|
||||||
|
|
||||||
if (amountOfVideos == 0)
|
|
||||||
showEmptyState();
|
if (thumbnailVideoRemoved) {
|
||||||
}, (@io.reactivex.annotations.NonNull Throwable throwable) -> {
|
updateThumbnailUrl();
|
||||||
onError(throwable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long videoCount = itemListAdapter.getItemsList().size();
|
||||||
|
setVideoCount(videoCount);
|
||||||
|
if (videoCount == 0) {
|
||||||
|
showEmptyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
hideLoading();
|
||||||
|
}, this::onError
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue