### Question:
SampleQueue implements TrackOutput { public void discardUpstreamSamples(int discardFromIndex) { totalBytesWritten = metadataQueue.discardUpstreamSamples(discardFromIndex); if (totalBytesWritten == 0 || totalBytesWritten == firstAllocationNode.startPosition) { clearAllocationNodes(firstAllocationNode); firstAllocationNode = new AllocationNode(totalBytesWritten, allocationLength); readAllocationNode = firstAllocationNode; writeAllocationNode = firstAllocationNode; } else { AllocationNode lastNodeToKeep = firstAllocationNode; while (totalBytesWritten > lastNodeToKeep.endPosition) { lastNodeToKeep = lastNodeToKeep.next; } AllocationNode firstNodeToDiscard = lastNodeToKeep.next; clearAllocationNodes(firstNodeToDiscard); lastNodeToKeep.next = new AllocationNode(lastNodeToKeep.endPosition, allocationLength); writeAllocationNode = totalBytesWritten == lastNodeToKeep.endPosition ? lastNodeToKeep.next : lastNodeToKeep; if (readAllocationNode == firstNodeToDiscard) { readAllocationNode = lastNodeToKeep.next; } } } SampleQueue(Allocator allocator); void reset(); void reset(boolean resetUpstreamFormat); void sourceId(int sourceId); void splice(); int getWriteIndex(); void discardUpstreamSamples(int discardFromIndex); boolean hasNextSample(); int getFirstIndex(); int getReadIndex(); int peekSourceId(); Format getUpstreamFormat(); long getLargestQueuedTimestampUs(); boolean isLastSampleQueued(); long getFirstTimestampUs(); void rewind(); void discardTo(long timeUs, boolean toKeyframe, boolean stopAtReadPosition); void discardToRead(); void discardToEnd(); int advanceToEnd(); int advanceTo(long timeUs, boolean toKeyframe, boolean allowTimeBeyondBuffer); boolean setReadPosition(int sampleIndex); int read(
      FormatHolder formatHolder,
      DecoderInputBuffer buffer,
      boolean formatRequired,
      boolean loadingFinished,
      long decodeOnlyUntilUs); void setUpstreamFormatChangeListener(UpstreamFormatChangedListener listener); void setSampleOffsetUs(long sampleOffsetUs); @Override void format(Format format); @Override int sampleData(ExtractorInput input, int length, boolean allowEndOfInput); @Override void sampleData(ParsableByteArray buffer, int length); @Override void sampleMetadata(
      long timeUs,
      @C.BufferFlags int flags,
      int size,
      int offset,
      @Nullable CryptoData cryptoData); static final int ADVANCE_FAILED; }### Answer:
@Test public void testDiscardUpstream() { writeTestData(); sampleQueue.discardUpstreamSamples(8); assertAllocationCount(10); sampleQueue.discardUpstreamSamples(7); assertAllocationCount(9); sampleQueue.discardUpstreamSamples(6); assertAllocationCount(7); sampleQueue.discardUpstreamSamples(5); assertAllocationCount(5); sampleQueue.discardUpstreamSamples(4); assertAllocationCount(4); sampleQueue.discardUpstreamSamples(3); assertAllocationCount(3); sampleQueue.discardUpstreamSamples(2); assertAllocationCount(2); sampleQueue.discardUpstreamSamples(1); assertAllocationCount(1); sampleQueue.discardUpstreamSamples(0); assertAllocationCount(0); assertReadFormat(false, FORMAT_2); assertNoSamplesToRead(FORMAT_2); }
@Test public void testDiscardUpstreamMulti() { writeTestData(); sampleQueue.discardUpstreamSamples(4); assertAllocationCount(4); sampleQueue.discardUpstreamSamples(0); assertAllocationCount(0); assertReadFormat(false, FORMAT_2); assertNoSamplesToRead(FORMAT_2); }
@Test public void testDiscardUpstreamBeforeRead() { writeTestData(); sampleQueue.discardUpstreamSamples(4); assertAllocationCount(4); assertReadTestData(null, 0, 4); assertReadFormat(false, FORMAT_2); assertNoSamplesToRead(FORMAT_2); }