// Repeatedly invokes provided callback passing to it sequence descriptors from the randomized // timeline until the callback returns false. On each successful invocation, it advances the // current position (cursor) in the timeline. void SequenceRandomizer::GetNextSequenceDescriptions( const std::function<bool(const RandomizedSequenceDescription&)>& callback, ClosedOpenChunkInterval& requiredChunks) { // Initialize the range to the current chunk. requiredChunks.m_begin = (ChunkIdType)std::min(m_currentChunkCursor, m_randomizedChunks.size() - 1); requiredChunks.m_end = requiredChunks.m_begin + 1; while (m_currentChunkCursor < m_randomizedChunks.size()) { size_t sequenceOffsetInsideChunk = m_currentSequenceCursor - m_randomizedChunks[m_currentChunkCursor].m_sequencePositionStart; RandomizedSequenceDescription& sequence = m_sequenceWindow[m_currentChunkCursor - m_chunkWindowBegin][sequenceOffsetInsideChunk]; if (!callback(sequence)) break; // Update the required chunk window. requiredChunks.m_begin = std::min(m_randomizedChunks[m_currentChunkCursor].m_randomizationWindow.m_begin, requiredChunks.m_begin); requiredChunks.m_end = std::max(m_randomizedChunks[m_currentChunkCursor].m_randomizationWindow.m_end, requiredChunks.m_end); // Update current cursor to the next sequence. m_currentSequenceCursor++; m_currentSampleCursor += sequence.m_numberOfSamples; if (sequenceOffsetInsideChunk + 1 >= m_randomizedChunks[m_currentChunkCursor].m_original->m_numberOfSequences) { // Moving to the next chunk, // Be careful, this invalidates the sequence from above. MoveChunkCursor(); } } }
// Gets next randomized sequence descriptions not exceeding the sample count. std::vector<RandomizedSequenceDescription> SequenceRandomizer::GetNextSequenceDescriptions(size_t sampleCount) { int samples = (int)sampleCount; std::vector<RandomizedSequenceDescription> result; result.reserve(sampleCount); bool firstSequence = true; while (samples > 0 && m_currentChunkCursor < m_randomizedChunks.size()) { size_t sequenceOffsetInsideChunk = m_currentSequenceCursor - m_randomizedChunks[m_currentChunkCursor].m_sequencePositionStart; RandomizedSequenceDescription* sequence = &m_sequenceWindow[m_currentChunkCursor - m_chunkWindowBegin][sequenceOffsetInsideChunk]; if (firstSequence || samples >= (int)sequence->m_numberOfSamples) { firstSequence = false; result.push_back(*sequence); m_currentSequenceCursor++; m_currentSampleCursor += (int)sequence->m_numberOfSamples; if (sequenceOffsetInsideChunk + 1 >= m_randomizedChunks[m_currentChunkCursor].m_original->m_numberOfSequences) { // Moving to the next chunk. MoveChunkCursor(); } } // Always decrease the available number of samples. samples -= (int)sequence->m_numberOfSamples; } return result; }