Skip to content

Commit 6ff9631

Browse files
rohitjoinstonihei
authored andcommitted
Fix FakeExtractorInput O(N^2) resizing during reads and peeks
Prevent `FakeExtractorInput` from performing expensive array resizing operations (`Booleans.ensureCapacity`) during standard reads or peeks where `simulatePartialReads` is disabled. Previously, the code attempted to resize the tracking arrays on every read operation. When `simulatePartialReads` is false, these arrays are initialized with a size of `0`, causing a mandatory allocation and array-copy for every single read. For large media files, this resulted in `O(N^2)` complexity and test timeouts. This change adds a guard to ensure resizing only occurs when the partial read simulation feature is actually active, restoring linear `O(N)` performance. #cherrypick PiperOrigin-RevId: 865504874 (cherry picked from commit dcd4463)
1 parent 9b355f7 commit 6ff9631

1 file changed

Lines changed: 18 additions & 17 deletions

File tree

libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeExtractorInput.java

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -265,25 +265,26 @@ private int getLengthToRead(int position, int requestedLength, boolean isPeek) {
265265
// If the requested length is non-zero, the end of the input will be read.
266266
return requestedLength == 0 ? 0 : Integer.MAX_VALUE;
267267
}
268-
int targetPosition = position + requestedLength;
269-
boolean[] partiallySatisfiedTargetPositions =
270-
isPeek ? partiallySatisfiedTargetPeekPositions : partiallySatisfiedTargetReadPositions;
271-
if (targetPosition >= partiallySatisfiedTargetPositions.length) {
272-
partiallySatisfiedTargetPositions =
273-
Booleans.ensureCapacity(
274-
partiallySatisfiedTargetPositions, targetPosition + 1, /* padding= */ 0);
275-
if (isPeek) {
276-
partiallySatisfiedTargetPeekPositions = partiallySatisfiedTargetPositions;
277-
} else {
278-
partiallySatisfiedTargetReadPositions = partiallySatisfiedTargetPositions;
268+
if (simulatePartialReads) {
269+
int targetPosition = position + requestedLength;
270+
boolean[] partiallySatisfiedTargetPositions =
271+
isPeek ? partiallySatisfiedTargetPeekPositions : partiallySatisfiedTargetReadPositions;
272+
if (targetPosition >= partiallySatisfiedTargetPositions.length) {
273+
partiallySatisfiedTargetPositions =
274+
Booleans.ensureCapacity(
275+
partiallySatisfiedTargetPositions, targetPosition + 1, /* padding= */ 0);
276+
if (isPeek) {
277+
partiallySatisfiedTargetPeekPositions = partiallySatisfiedTargetPositions;
278+
} else {
279+
partiallySatisfiedTargetReadPositions = partiallySatisfiedTargetPositions;
280+
}
281+
}
282+
if (requestedLength > 1 && !partiallySatisfiedTargetPositions[targetPosition]) {
283+
partiallySatisfiedTargetPositions[targetPosition] = true;
284+
return 1;
279285
}
280286
}
281-
if (simulatePartialReads
282-
&& requestedLength > 1
283-
&& !partiallySatisfiedTargetPositions[targetPosition]) {
284-
partiallySatisfiedTargetPositions[targetPosition] = true;
285-
return 1;
286-
}
287+
287288
return min(requestedLength, data.length - position);
288289
}
289290

0 commit comments

Comments
 (0)