mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Support removal of ranges from ShuffleOrders
This allows more efficient range removals and is consistent with addition, which supports adding multiple elements in a single operation. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=222396310
This commit is contained in:
parent
265462bcbd
commit
5f12b065a4
@ -570,9 +570,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
|
||||
if (fromIndex == 0 && toIndex == shuffleOrder.getLength()) {
|
||||
shuffleOrder = shuffleOrder.cloneAndClear();
|
||||
} else {
|
||||
for (int index = toIndex - 1; index >= fromIndex; index--) {
|
||||
shuffleOrder = shuffleOrder.cloneAndRemove(index);
|
||||
}
|
||||
shuffleOrder = shuffleOrder.cloneAndRemove(fromIndex, toIndex);
|
||||
}
|
||||
for (int index = toIndex - 1; index >= fromIndex; index--) {
|
||||
removeMediaSourceInternal(index);
|
||||
@ -581,7 +579,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
|
||||
break;
|
||||
case MSG_MOVE:
|
||||
MessageData<Integer> moveMessage = (MessageData<Integer>) Util.castNonNull(message);
|
||||
shuffleOrder = shuffleOrder.cloneAndRemove(moveMessage.index);
|
||||
shuffleOrder = shuffleOrder.cloneAndRemove(moveMessage.index, moveMessage.index + 1);
|
||||
shuffleOrder = shuffleOrder.cloneAndInsert(moveMessage.customData, 1);
|
||||
moveMediaSourceInternal(moveMessage.index, moveMessage.customData);
|
||||
scheduleListenerNotification(moveMessage.actionOnCompletion);
|
||||
|
@ -135,15 +135,16 @@ public interface ShuffleOrder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShuffleOrder cloneAndRemove(int removalIndex) {
|
||||
int[] newShuffled = new int[shuffled.length - 1];
|
||||
boolean foundRemovedElement = false;
|
||||
public ShuffleOrder cloneAndRemove(int indexFrom, int indexToExclusive) {
|
||||
int numberOfElementsToRemove = indexToExclusive - indexFrom;
|
||||
int[] newShuffled = new int[shuffled.length - numberOfElementsToRemove];
|
||||
int foundElementsCount = 0;
|
||||
for (int i = 0; i < shuffled.length; i++) {
|
||||
if (shuffled[i] == removalIndex) {
|
||||
foundRemovedElement = true;
|
||||
if (shuffled[i] >= indexFrom && shuffled[i] < indexToExclusive) {
|
||||
foundElementsCount++;
|
||||
} else {
|
||||
newShuffled[foundRemovedElement ? i - 1 : i] = shuffled[i] > removalIndex
|
||||
? shuffled[i] - 1 : shuffled[i];
|
||||
newShuffled[i - foundElementsCount] =
|
||||
shuffled[i] >= indexFrom ? shuffled[i] - numberOfElementsToRemove : shuffled[i];
|
||||
}
|
||||
}
|
||||
return new DefaultShuffleOrder(newShuffled, new Random(random.nextLong()));
|
||||
@ -213,8 +214,8 @@ public interface ShuffleOrder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShuffleOrder cloneAndRemove(int removalIndex) {
|
||||
return new UnshuffledShuffleOrder(length - 1);
|
||||
public ShuffleOrder cloneAndRemove(int indexFrom, int indexToExclusive) {
|
||||
return new UnshuffledShuffleOrder(length - indexToExclusive + indexFrom);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -268,12 +269,14 @@ public interface ShuffleOrder {
|
||||
ShuffleOrder cloneAndInsert(int insertionIndex, int insertionCount);
|
||||
|
||||
/**
|
||||
* Returns a copy of the shuffle order with one element removed.
|
||||
* Returns a copy of the shuffle order with a range of elements removed.
|
||||
*
|
||||
* @param removalIndex The index of the element in the unshuffled order which is to be removed.
|
||||
* @return A copy of this {@link ShuffleOrder} without the removed element.
|
||||
* @param indexFrom The starting index in the unshuffled order of the range to remove.
|
||||
* @param indexToExclusive The smallest index (must be greater or equal to {@code indexFrom}) that
|
||||
* will not be removed.
|
||||
* @return A copy of this {@link ShuffleOrder} without the elements in the removed range.
|
||||
*/
|
||||
ShuffleOrder cloneAndRemove(int removalIndex);
|
||||
ShuffleOrder cloneAndRemove(int indexFrom, int indexToExclusive);
|
||||
|
||||
/** Returns a copy of the shuffle order with all elements removed. */
|
||||
ShuffleOrder cloneAndClear();
|
||||
|
@ -45,10 +45,32 @@ public final class ShuffleOrderTest {
|
||||
testCloneAndInsert(new DefaultShuffleOrder(initialLength, RANDOM_SEED), insertionPoint, 5);
|
||||
}
|
||||
}
|
||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 0);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 2);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 4);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(1, RANDOM_SEED), 0);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 0, 1);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 2, 3);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 4, 5);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(1, RANDOM_SEED), 0, 1);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 0, 1000);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 0, 999);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 0, 500);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 100, 600);
|
||||
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 500, 1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultShuffleOrderSideloaded() {
|
||||
int[] shuffledIndices = new int[] {2, 1, 0, 4, 3};
|
||||
ShuffleOrder shuffleOrder = new DefaultShuffleOrder(shuffledIndices, RANDOM_SEED);
|
||||
assertThat(shuffleOrder.getFirstIndex()).isEqualTo(2);
|
||||
assertThat(shuffleOrder.getLastIndex()).isEqualTo(3);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
assertThat(shuffleOrder.getNextIndex(shuffledIndices[i])).isEqualTo(shuffledIndices[i + 1]);
|
||||
}
|
||||
assertThat(shuffleOrder.getNextIndex(3)).isEqualTo(C.INDEX_UNSET);
|
||||
for (int i = 4; i > 0; i--) {
|
||||
assertThat(shuffleOrder.getPreviousIndex(shuffledIndices[i]))
|
||||
.isEqualTo(shuffledIndices[i - 1]);
|
||||
}
|
||||
assertThat(shuffleOrder.getPreviousIndex(2)).isEqualTo(C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -63,10 +85,15 @@ public final class ShuffleOrderTest {
|
||||
testCloneAndInsert(new UnshuffledShuffleOrder(initialLength), insertionPoint, 5);
|
||||
}
|
||||
}
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 0);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 2);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 4);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(1), 0);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 0, 1);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 2, 3);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 4, 5);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(1), 0, 1);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 0, 1000);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 0, 999);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 0, 500);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 100, 600);
|
||||
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 500, 1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -79,23 +106,6 @@ public final class ShuffleOrderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSideloadedShuffleOrder() {
|
||||
int[] shuffledIndices = new int[] {2, 1, 0, 4, 3};
|
||||
ShuffleOrder shuffleOrder = new DefaultShuffleOrder(shuffledIndices, RANDOM_SEED);
|
||||
assertThat(shuffleOrder.getFirstIndex()).isEqualTo(2);
|
||||
assertThat(shuffleOrder.getLastIndex()).isEqualTo(3);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
assertThat(shuffleOrder.getNextIndex(shuffledIndices[i])).isEqualTo(shuffledIndices[i + 1]);
|
||||
}
|
||||
assertThat(shuffleOrder.getNextIndex(3)).isEqualTo(C.INDEX_UNSET);
|
||||
for (int i = 4; i > 0; i--) {
|
||||
assertThat(shuffleOrder.getPreviousIndex(shuffledIndices[i]))
|
||||
.isEqualTo(shuffledIndices[i - 1]);
|
||||
}
|
||||
assertThat(shuffleOrder.getPreviousIndex(2)).isEqualTo(C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
private static void assertShuffleOrderCorrectness(ShuffleOrder shuffleOrder, int length) {
|
||||
assertThat(shuffleOrder.getLength()).isEqualTo(length);
|
||||
if (length == 0) {
|
||||
@ -137,22 +147,24 @@ public final class ShuffleOrderTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void testCloneAndRemove(ShuffleOrder shuffleOrder, int position) {
|
||||
ShuffleOrder newOrder = shuffleOrder.cloneAndRemove(position);
|
||||
assertShuffleOrderCorrectness(newOrder, shuffleOrder.getLength() - 1);
|
||||
private static void testCloneAndRemove(
|
||||
ShuffleOrder shuffleOrder, int indexFrom, int indexToExclusive) {
|
||||
int numberOfElementsToRemove = indexToExclusive - indexFrom;
|
||||
ShuffleOrder newOrder = shuffleOrder.cloneAndRemove(indexFrom, indexToExclusive);
|
||||
assertShuffleOrderCorrectness(newOrder, shuffleOrder.getLength() - numberOfElementsToRemove);
|
||||
// Assert all elements still have the relative same order
|
||||
for (int i = 0; i < shuffleOrder.getLength(); i++) {
|
||||
if (i == position) {
|
||||
if (i >= indexFrom && i < indexToExclusive) {
|
||||
continue;
|
||||
}
|
||||
int expectedNextIndex = shuffleOrder.getNextIndex(i);
|
||||
if (expectedNextIndex == position) {
|
||||
while (expectedNextIndex >= indexFrom && expectedNextIndex < indexToExclusive) {
|
||||
expectedNextIndex = shuffleOrder.getNextIndex(expectedNextIndex);
|
||||
}
|
||||
if (expectedNextIndex != C.INDEX_UNSET && expectedNextIndex >= position) {
|
||||
expectedNextIndex--;
|
||||
if (expectedNextIndex != C.INDEX_UNSET && expectedNextIndex >= indexFrom) {
|
||||
expectedNextIndex -= numberOfElementsToRemove;
|
||||
}
|
||||
int newNextIndex = newOrder.getNextIndex(i < position ? i : i - 1);
|
||||
int newNextIndex = newOrder.getNextIndex(i < indexFrom ? i : i - numberOfElementsToRemove);
|
||||
assertThat(newNextIndex).isEqualTo(expectedNextIndex);
|
||||
}
|
||||
}
|
||||
|
@ -61,8 +61,8 @@ public final class FakeShuffleOrder implements ShuffleOrder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShuffleOrder cloneAndRemove(int removalIndex) {
|
||||
return new FakeShuffleOrder(length - 1);
|
||||
public ShuffleOrder cloneAndRemove(int indexFrom, int indexToExclusive) {
|
||||
return new FakeShuffleOrder(length - indexToExclusive + indexFrom);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user