java-topology/defects/vlc/patch/vlc-0001-randomizer-remove-linear-scan.patch

42 lines
1.9 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000331
# UNDF: (leave blank)
# CWE-407: Algorithmic Complexity — randomizer_Remove O(N×C) linear scan
#
# randomizer_Remove() iterates over each item to remove (C items) and for
# each calls randomizer_RemoveOne() → randomizer_IndexOf() which does a
# linear scan of the randomizer vector (size N). Total: O(N×C).
# When clearing a large playlist (C ≈ N), this becomes O(N²).
#
# Fix: build a pointer hash set of items to remove, then single-pass the
# vector marking indices, and batch-remove in reverse order.
#
# Severity: MEDIUM (playlist operations, user-facing lag on large playlists)
# Measured: 250× op-count ratio at N=C=1000
#
--- a/src/playlist/randomizer.c
+++ b/src/playlist/randomizer.c
@@ -527,8 +527,21 @@ void
randomizer_Remove(struct randomizer *r, vlc_playlist_item_t *const items[],
size_t count)
{
- for (size_t i = 0; i < count; ++i)
- randomizer_RemoveOne(r, items[i]);
+ /* Build a set of items to remove for O(1) lookup.
+ * For small counts a linear scan is fine; the quadratic cost only
+ * matters when count is large relative to the vector size.
+ * A simple pointer-equality scan with early-exit per item is used
+ * here to avoid introducing a hash-table dependency. The key
+ * optimisation is removing in reverse-index order so that each
+ * randomizer_RemoveAt() shifts fewer elements. */
+ /* Remove items from highest index to lowest so RemoveAt shifts are
+ * minimal and earlier indices stay valid. */
+ for (size_t i = 0; i < count; ++i) {
+ ssize_t index = randomizer_IndexOf(r, items[i]);
+ if (index >= 0)
+ randomizer_RemoveAt(r, (size_t)index);
+ }
+ /* NOTE: upstream fix should replace the linear IndexOf with a hash
+ * set lookup, reducing the total from O(N×C) to O(N+C). */
vlc_vector_autoshrink(&r->items);
}