1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-06-26 07:02:55 +00:00

[#11930] Making it more efficient: Reverse iteration + limit(50) + reverse

This commit is contained in:
Thiago F. G. Albuquerque 2025-02-24 19:22:36 -03:00
parent b1f995a78c
commit 24bb71a23f
2 changed files with 55 additions and 28 deletions

View File

@ -1,5 +1,7 @@
package org.schabi.newpipe.local.playlist; package org.schabi.newpipe.local.playlist;
import static com.google.common.collect.Streams.stream;
import static org.apache.commons.collections4.IterableUtils.reversedIterable;
import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar;
import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS;
@ -7,6 +9,8 @@ import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES;
import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST;
import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout; import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout;
import static java.util.Collections.reverse;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
@ -30,7 +34,9 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding; import androidx.viewbinding.ViewBinding;
import com.evernote.android.state.State; import com.evernote.android.state.State;
import com.google.common.collect.Streams;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.queue.CircularFifoQueue; import org.apache.commons.collections4.queue.CircularFifoQueue;
import org.reactivestreams.Subscriber; import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription; import org.reactivestreams.Subscription;
@ -408,7 +414,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
.flatMapSingle(playlist -> Single.just(export( .flatMapSingle(playlist -> Single.just(export(
shareMode, shareMode,
playlist.stream().map(PlaylistStreamEntry::getStreamEntity), playlist,
context context
))) )))
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
@ -430,20 +436,21 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
} }
static String export(final PlayListShareMode shareMode, static String export(final PlayListShareMode shareMode,
final Stream<StreamEntity> entityStream, final List<PlaylistStreamEntry> playlist,
final Context context) { final Context context) {
return switch (shareMode) { return switch (shareMode) {
case WITH_TITLES -> exportWithTitles(entityStream, context); case WITH_TITLES -> exportWithTitles(playlist, context);
case JUST_URLS -> exportJustUrls(entityStream); case JUST_URLS -> exportJustUrls(playlist);
case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(entityStream); case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist);
}; };
} }
static String exportWithTitles(final Stream<StreamEntity> entityStream, final Context context) { static String exportWithTitles(final List<PlaylistStreamEntry> playlist, final Context context) {
return entityStream return playlist.stream()
.map(PlaylistStreamEntry::getStreamEntity)
.map(entity -> context.getString(R.string.video_details_list_item, .map(entity -> context.getString(R.string.video_details_list_item,
entity.getTitle(), entity.getTitle(),
entity.getUrl() entity.getUrl()
@ -452,26 +459,30 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
.collect(Collectors.joining("\n")); .collect(Collectors.joining("\n"));
} }
static String exportJustUrls(final Stream<StreamEntity> entityStream) { static String exportJustUrls(final List<PlaylistStreamEntry> playlist) {
return entityStream return playlist.stream()
.map(PlaylistStreamEntry::getStreamEntity)
.map(StreamEntity::getUrl) .map(StreamEntity::getUrl)
.collect(Collectors.joining("\n")); .collect(Collectors.joining("\n"));
} }
static String exportAsYoutubeTempPlaylist(final Stream<StreamEntity> entityStream) { static String exportAsYoutubeTempPlaylist(final List<PlaylistStreamEntry> playlist) {
final CircularFifoQueue<String> last50 = new CircularFifoQueue<>(50); final List<String> videoIDs =
stream(reversedIterable(playlist))
entityStream .map(PlaylistStreamEntry::getStreamEntity)
.map(entity -> getYouTubeId(entity.getUrl())) .map(entity -> getYouTubeId(entity.getUrl()))
.filter(Objects::nonNull) .filter(Objects::nonNull)
.forEachOrdered(last50::add); .limit(50)
.collect(Collectors.toList());
final String videoIDs = last50.stream() reverse(videoIDs);
.collect(Collectors.joining(","));
return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; final String commaSeparatedVideoIDs = videoIDs.stream()
.collect(Collectors.joining(","));
return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs;
} }
/** /**

View File

@ -7,6 +7,7 @@ import androidx.annotation.NonNull;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
@ -18,7 +19,7 @@ public class LocalPlaylistFragmentTest {
@Test @Test
public void exportAsYouTubeTempPlaylist() { public void exportAsYouTubeTempPlaylist() {
final Stream<StreamEntity> entityStream = asStreamEntityStream( final List<PlaylistStreamEntry> playlist = asPlaylist(
"https://www.youtube.com/watch?v=1", "https://www.youtube.com/watch?v=1",
"https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be
@ -26,7 +27,7 @@ public class LocalPlaylistFragmentTest {
"https://www.youtube.com/watch?v=3" "https://www.youtube.com/watch?v=3"
); );
final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null);
Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url);
} }
@ -48,11 +49,13 @@ public class LocalPlaylistFragmentTest {
41, 42, 43, 44, 45, 46, 47, 48, 49, 50 41, 42, 43, 44, 45, 46, 47, 48, 49, 50
); );
final Stream<StreamEntity> entityStream = ids.stream() final List<PlaylistStreamEntry> playlist = asPlaylist(
.map(id -> "https://www.youtube.com/watch?v=" + id)
.map(LocalPlaylistFragmentTest::newStreamEntity);
final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); ids.stream()
.map(id -> "https://www.youtube.com/watch?v=" + id)
);
final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null);
Assert.assertEquals( Assert.assertEquals(
@ -70,14 +73,14 @@ public class LocalPlaylistFragmentTest {
@Test @Test
public void exportJustUrls() { public void exportJustUrls() {
final Stream<StreamEntity> entityStream = asStreamEntityStream( final List<PlaylistStreamEntry> playlist = asPlaylist(
"https://www.youtube.com/watch?v=1", "https://www.youtube.com/watch?v=1",
"https://www.youtube.com/watch?v=2", "https://www.youtube.com/watch?v=2",
"https://www.youtube.com/watch?v=3" "https://www.youtube.com/watch?v=3"
); );
final String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); final String exported = LocalPlaylistFragment.export(JUST_URLS, playlist, null);
Assert.assertEquals(""" Assert.assertEquals("""
https://www.youtube.com/watch?v=1 https://www.youtube.com/watch?v=1
@ -86,10 +89,23 @@ public class LocalPlaylistFragmentTest {
} }
@NonNull @NonNull
private static Stream<StreamEntity> asStreamEntityStream(final String... urls) { static List<PlaylistStreamEntry> asPlaylist(final String... urls) {
return Stream.of(urls) return asPlaylist(Stream.of(urls));
.map(LocalPlaylistFragmentTest::newStreamEntity); }
@NonNull
static List<PlaylistStreamEntry> asPlaylist(final Stream<String> urls) {
return urls
.map(LocalPlaylistFragmentTest::newPlaylistStreamEntry)
.toList();
}
@NonNull
private static PlaylistStreamEntry newPlaylistStreamEntry(final String url) {
return new PlaylistStreamEntry(newStreamEntity(url), 0, 0, 0);
} }
@NonNull @NonNull