Skip to content

Commit 7b6e004

Browse files
committed
Implement dynamic write threshold adjustment based on buffer usage
1 parent 5b974ae commit 7b6e004

4 files changed

Lines changed: 79 additions & 4 deletions

File tree

Source/Processors/RecordNode/DataQueue.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
#include "DataQueue.h"
25+
#include <climits>
2526

2627
DataQueue::DataQueue (int blockSize, int nBlocks) : m_buffer (0, blockSize * nBlocks),
2728
m_numChans (0),
@@ -36,7 +37,7 @@ DataQueue::~DataQueue()
3637
{
3738
}
3839

39-
int DataQueue::getBlockSize()
40+
int DataQueue::getBlockSize() const
4041
{
4142
return m_blockSize;
4243
}

Source/Processors/RecordNode/DataQueue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class DataQueue
115115
const SynchronizedTimestampBuffer& getTimestampBufferReference() const;
116116

117117
/** Returns the current block size*/
118-
int getBlockSize();
118+
int getBlockSize() const;
119119

120120
private:
121121
/** Fills the sample number buffer for the stream */

Source/Processors/RecordNode/RecordThread.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,54 @@ RecordThread::~RecordThread()
4949
{
5050
}
5151

52+
void RecordThread::adjustWriteThresholdsBasedOnBufferUsage (float bufferUsage)
53+
{
54+
// Dynamic adjustment strategy:
55+
// - Low usage (0-40%): Use larger batches for efficiency
56+
// - Medium usage (40-70%): Use moderate batches
57+
// - High usage (70-85%): Use smaller batches, write more frequently
58+
// - Critical usage (85%+): Minimize delay, write as soon as possible
59+
60+
int oldMin = m_minWriteSamples;
61+
int oldMax = m_maxWriteSamples;
62+
63+
if (bufferUsage < 0.4f)
64+
{
65+
// Low buffer usage - optimize for disk efficiency with larger batches
66+
m_minWriteSamples = BLOCK_DEFAULT_MIN_WRITE_SAMPLES;
67+
m_maxWriteSamples = BLOCK_DEFAULT_MAX_WRITE_SAMPLES;
68+
}
69+
else if (bufferUsage < 0.7f)
70+
{
71+
// Medium buffer usage - balanced approach
72+
m_minWriteSamples = BLOCK_DEFAULT_MIN_WRITE_SAMPLES / 2; // 256
73+
m_maxWriteSamples = BLOCK_DEFAULT_MAX_WRITE_SAMPLES / 2; // 2048
74+
}
75+
else if (bufferUsage < 0.85f)
76+
{
77+
// High buffer usage - prioritize emptying buffer
78+
m_minWriteSamples = BLOCK_DEFAULT_MIN_WRITE_SAMPLES / 4; // 128
79+
m_maxWriteSamples = BLOCK_DEFAULT_MAX_WRITE_SAMPLES / 4; // 1024
80+
}
81+
else
82+
{
83+
// Critical buffer usage - write immediately with any available data
84+
m_minWriteSamples = 64; // Very low threshold
85+
m_maxWriteSamples = 512; // Smaller batches to reduce latency
86+
}
87+
88+
// Ensure max >= min to avoid deadlock
89+
if (m_maxWriteSamples < m_minWriteSamples)
90+
m_maxWriteSamples = m_minWriteSamples;
91+
92+
// Log threshold changes to help monitor adaptive behavior
93+
if (oldMin != m_minWriteSamples || oldMax != m_maxWriteSamples)
94+
{
95+
LOGC ("Buffer usage: ", int (bufferUsage * 100), "% - Adjusted write thresholds: MIN=",
96+
m_minWriteSamples, " MAX=", m_maxWriteSamples);
97+
}
98+
}
99+
52100
void RecordThread::setEngine (RecordEngine* engine)
53101
{
54102
m_engine = engine;
@@ -170,7 +218,28 @@ void RecordThread::run()
170218

171219
//4 - Normal loop
172220
while (! threadShouldExit())
221+
{
222+
// Calculate maximum buffer usage across all streams to adjust write strategy
223+
float maxBufferUsage = 0.0f;
224+
for (int streamIdx = 0; streamIdx < numStreams; streamIdx++)
225+
{
226+
DataQueue* queue = (*m_dataQueues)[streamIdx];
227+
if (queue != nullptr)
228+
{
229+
// Calculate buffer usage based on samples ready vs total capacity
230+
int samplesReady = queue->getNumSamplesReady();
231+
int totalCapacity = queue->getBlockSize() * DATA_BUFFER_NBLOCKS;
232+
float usage = (float) samplesReady / (float) totalCapacity;
233+
if (usage > maxBufferUsage)
234+
maxBufferUsage = usage;
235+
}
236+
}
237+
238+
// Dynamically adjust write thresholds based on buffer fullness
239+
adjustWriteThresholdsBasedOnBufferUsage (maxBufferUsage);
240+
173241
writeData (m_minWriteSamples, m_maxWriteSamples, BLOCK_MAX_WRITE_EVENTS, BLOCK_MAX_WRITE_SPIKES);
242+
}
174243

175244
//LOGD(__FUNCTION__, " Exiting record thread");
176245
//5 - Before closing the thread, try to write the remaining samples

Source/Processors/RecordNode/RecordThread.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
// - Low channel count = small writes (fine for low data rates, keeps latency low)
3939
//
4040

41-
#define BLOCK_DEFAULT_MIN_WRITE_SAMPLES 8192
42-
#define BLOCK_DEFAULT_MAX_WRITE_SAMPLES 16384
41+
#define BLOCK_DEFAULT_MIN_WRITE_SAMPLES 512
42+
#define BLOCK_DEFAULT_MAX_WRITE_SAMPLES 4096
4343
#define BLOCK_MAX_WRITE_EVENTS 50000
4444
#define BLOCK_MAX_WRITE_SPIKES 50000
4545

@@ -139,6 +139,11 @@ class RecordThread : public Thread
139139
int m_minWriteSamples; // Minimum samples before writing
140140
int m_maxWriteSamples; // Maximum samples per write batch
141141

142+
/** Dynamically adjusts write thresholds based on buffer fullness
143+
* @param bufferUsage Current buffer usage (0.0 to 1.0)
144+
*/
145+
void adjustWriteThresholdsBasedOnBufferUsage (float bufferUsage);
146+
142147
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RecordThread);
143148
};
144149

0 commit comments

Comments
 (0)