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()) {
|
if (fromIndex == 0 && toIndex == shuffleOrder.getLength()) {
|
||||||
shuffleOrder = shuffleOrder.cloneAndClear();
|
shuffleOrder = shuffleOrder.cloneAndClear();
|
||||||
} else {
|
} else {
|
||||||
for (int index = toIndex - 1; index >= fromIndex; index--) {
|
shuffleOrder = shuffleOrder.cloneAndRemove(fromIndex, toIndex);
|
||||||
shuffleOrder = shuffleOrder.cloneAndRemove(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int index = toIndex - 1; index >= fromIndex; index--) {
|
for (int index = toIndex - 1; index >= fromIndex; index--) {
|
||||||
removeMediaSourceInternal(index);
|
removeMediaSourceInternal(index);
|
||||||
@ -581,7 +579,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
|
|||||||
break;
|
break;
|
||||||
case MSG_MOVE:
|
case MSG_MOVE:
|
||||||
MessageData<Integer> moveMessage = (MessageData<Integer>) Util.castNonNull(message);
|
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);
|
shuffleOrder = shuffleOrder.cloneAndInsert(moveMessage.customData, 1);
|
||||||
moveMediaSourceInternal(moveMessage.index, moveMessage.customData);
|
moveMediaSourceInternal(moveMessage.index, moveMessage.customData);
|
||||||
scheduleListenerNotification(moveMessage.actionOnCompletion);
|
scheduleListenerNotification(moveMessage.actionOnCompletion);
|
||||||
|
@ -135,15 +135,16 @@ public interface ShuffleOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ShuffleOrder cloneAndRemove(int removalIndex) {
|
public ShuffleOrder cloneAndRemove(int indexFrom, int indexToExclusive) {
|
||||||
int[] newShuffled = new int[shuffled.length - 1];
|
int numberOfElementsToRemove = indexToExclusive - indexFrom;
|
||||||
boolean foundRemovedElement = false;
|
int[] newShuffled = new int[shuffled.length - numberOfElementsToRemove];
|
||||||
|
int foundElementsCount = 0;
|
||||||
for (int i = 0; i < shuffled.length; i++) {
|
for (int i = 0; i < shuffled.length; i++) {
|
||||||
if (shuffled[i] == removalIndex) {
|
if (shuffled[i] >= indexFrom && shuffled[i] < indexToExclusive) {
|
||||||
foundRemovedElement = true;
|
foundElementsCount++;
|
||||||
} else {
|
} else {
|
||||||
newShuffled[foundRemovedElement ? i - 1 : i] = shuffled[i] > removalIndex
|
newShuffled[i - foundElementsCount] =
|
||||||
? shuffled[i] - 1 : shuffled[i];
|
shuffled[i] >= indexFrom ? shuffled[i] - numberOfElementsToRemove : shuffled[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new DefaultShuffleOrder(newShuffled, new Random(random.nextLong()));
|
return new DefaultShuffleOrder(newShuffled, new Random(random.nextLong()));
|
||||||
@ -213,8 +214,8 @@ public interface ShuffleOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ShuffleOrder cloneAndRemove(int removalIndex) {
|
public ShuffleOrder cloneAndRemove(int indexFrom, int indexToExclusive) {
|
||||||
return new UnshuffledShuffleOrder(length - 1);
|
return new UnshuffledShuffleOrder(length - indexToExclusive + indexFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -268,12 +269,14 @@ public interface ShuffleOrder {
|
|||||||
ShuffleOrder cloneAndInsert(int insertionIndex, int insertionCount);
|
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.
|
* @param indexFrom The starting index in the unshuffled order of the range to remove.
|
||||||
* @return A copy of this {@link ShuffleOrder} without the removed element.
|
* @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. */
|
/** Returns a copy of the shuffle order with all elements removed. */
|
||||||
ShuffleOrder cloneAndClear();
|
ShuffleOrder cloneAndClear();
|
||||||
|
@ -45,10 +45,32 @@ public final class ShuffleOrderTest {
|
|||||||
testCloneAndInsert(new DefaultShuffleOrder(initialLength, RANDOM_SEED), insertionPoint, 5);
|
testCloneAndInsert(new DefaultShuffleOrder(initialLength, RANDOM_SEED), insertionPoint, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 0);
|
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 0, 1);
|
||||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 2);
|
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 2, 3);
|
||||||
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 4);
|
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 4, 5);
|
||||||
testCloneAndRemove(new DefaultShuffleOrder(1, RANDOM_SEED), 0);
|
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
|
@Test
|
||||||
@ -63,10 +85,15 @@ public final class ShuffleOrderTest {
|
|||||||
testCloneAndInsert(new UnshuffledShuffleOrder(initialLength), insertionPoint, 5);
|
testCloneAndInsert(new UnshuffledShuffleOrder(initialLength), insertionPoint, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 0);
|
testCloneAndRemove(new UnshuffledShuffleOrder(5), 0, 1);
|
||||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 2);
|
testCloneAndRemove(new UnshuffledShuffleOrder(5), 2, 3);
|
||||||
testCloneAndRemove(new UnshuffledShuffleOrder(5), 4);
|
testCloneAndRemove(new UnshuffledShuffleOrder(5), 4, 5);
|
||||||
testCloneAndRemove(new UnshuffledShuffleOrder(1), 0);
|
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
|
@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) {
|
private static void assertShuffleOrderCorrectness(ShuffleOrder shuffleOrder, int length) {
|
||||||
assertThat(shuffleOrder.getLength()).isEqualTo(length);
|
assertThat(shuffleOrder.getLength()).isEqualTo(length);
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
@ -137,22 +147,24 @@ public final class ShuffleOrderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testCloneAndRemove(ShuffleOrder shuffleOrder, int position) {
|
private static void testCloneAndRemove(
|
||||||
ShuffleOrder newOrder = shuffleOrder.cloneAndRemove(position);
|
ShuffleOrder shuffleOrder, int indexFrom, int indexToExclusive) {
|
||||||
assertShuffleOrderCorrectness(newOrder, shuffleOrder.getLength() - 1);
|
int numberOfElementsToRemove = indexToExclusive - indexFrom;
|
||||||
|
ShuffleOrder newOrder = shuffleOrder.cloneAndRemove(indexFrom, indexToExclusive);
|
||||||
|
assertShuffleOrderCorrectness(newOrder, shuffleOrder.getLength() - numberOfElementsToRemove);
|
||||||
// Assert all elements still have the relative same order
|
// Assert all elements still have the relative same order
|
||||||
for (int i = 0; i < shuffleOrder.getLength(); i++) {
|
for (int i = 0; i < shuffleOrder.getLength(); i++) {
|
||||||
if (i == position) {
|
if (i >= indexFrom && i < indexToExclusive) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int expectedNextIndex = shuffleOrder.getNextIndex(i);
|
int expectedNextIndex = shuffleOrder.getNextIndex(i);
|
||||||
if (expectedNextIndex == position) {
|
while (expectedNextIndex >= indexFrom && expectedNextIndex < indexToExclusive) {
|
||||||
expectedNextIndex = shuffleOrder.getNextIndex(expectedNextIndex);
|
expectedNextIndex = shuffleOrder.getNextIndex(expectedNextIndex);
|
||||||
}
|
}
|
||||||
if (expectedNextIndex != C.INDEX_UNSET && expectedNextIndex >= position) {
|
if (expectedNextIndex != C.INDEX_UNSET && expectedNextIndex >= indexFrom) {
|
||||||
expectedNextIndex--;
|
expectedNextIndex -= numberOfElementsToRemove;
|
||||||
}
|
}
|
||||||
int newNextIndex = newOrder.getNextIndex(i < position ? i : i - 1);
|
int newNextIndex = newOrder.getNextIndex(i < indexFrom ? i : i - numberOfElementsToRemove);
|
||||||
assertThat(newNextIndex).isEqualTo(expectedNextIndex);
|
assertThat(newNextIndex).isEqualTo(expectedNextIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ public final class FakeShuffleOrder implements ShuffleOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ShuffleOrder cloneAndRemove(int removalIndex) {
|
public ShuffleOrder cloneAndRemove(int indexFrom, int indexToExclusive) {
|
||||||
return new FakeShuffleOrder(length - 1);
|
return new FakeShuffleOrder(length - indexToExclusive + indexFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user