summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-10-12 00:20:19 -0700
committerRichard Linden <none@none>2012-10-12 00:20:19 -0700
commit0f58ca02cdec62711eadb82ba28fcff08faef2ee (patch)
tree3816a47094ac89b7cc54fbf69426e2e634e8c622 /indra/llcommon
parentb3107e37643743118840d3f5437e62196bae3581 (diff)
SH-3275 WIP Update viewer metrics system to be more flexible
cleaned up accumulator merging logic introduced frame recording to LLTrace directly instead of going through LLViewerStats moved consumer code over to frame recording instead of whatever the current active recording was
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/lltrace.h49
-rw-r--r--indra/llcommon/lltracerecording.cpp214
-rw-r--r--indra/llcommon/lltracerecording.h251
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp73
-rw-r--r--indra/llcommon/lltracethreadrecorder.h7
5 files changed, 321 insertions, 273 deletions
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index a6334e176b..0c618a2f4b 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -101,16 +101,6 @@ namespace LLTrace
}
}
- void addDeltas(const AccumulatorBuffer<ACCUMULATOR>& start, const AccumulatorBuffer<ACCUMULATOR>& finish)
- {
- llassert(mNextStorageSlot == start.mNextStorageSlot && mNextStorageSlot == finish.mNextStorageSlot);
-
- for (size_t i = 0; i < mNextStorageSlot; i++)
- {
- mStorage[i].addDeltas(start.mStorage[i], finish.mStorage[i]);
- }
- }
-
void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
{
for (size_t i = 0; i < mNextStorageSlot; i++)
@@ -203,11 +193,12 @@ namespace LLTrace
public:
MeasurementAccumulator()
: mSum(0),
- mMin(0),
- mMax(0),
+ mMin(std::numeric_limits<T>::max()),
+ mMax(std::numeric_limits<T>::min()),
mMean(0),
mVarianceSum(0),
- mNumSamples(0)
+ mNumSamples(0),
+ mLastValue(0)
{}
LL_FORCE_INLINE void sample(T value)
@@ -251,20 +242,27 @@ namespace LLTrace
sd_2 = other.getStandardDeviation();
// combine variance (and hence standard deviation) of 2 different sized sample groups using
// the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
- mVarianceSum = (F32)mNumSamples
+ if (n_1 == 0)
+ {
+ mVarianceSum = other.mVarianceSum;
+ }
+ else if (n_2 == 0)
+ {
+ // don't touch variance
+ // mVarianceSum = mVarianceSum;
+ }
+ else
+ {
+ mVarianceSum = (F32)mNumSamples
* ((((n_1 - 1.f) * sd_1 * sd_1)
+ ((n_2 - 1.f) * sd_2 * sd_2)
+ (((n_1 * n_2) / (n_1 + n_2))
* ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
/ (n_1 + n_2 - 1.f));
+ }
mLastValue = other.mLastValue;
}
- void addDeltas(const MeasurementAccumulator<T>& start, const MeasurementAccumulator<T>& finish)
- {
- llerrs << "Delta merge invalid for measurement accumulators" << llendl;
- }
-
void reset()
{
mNumSamples = 0;
@@ -313,12 +311,6 @@ namespace LLTrace
mNumSamples += other.mNumSamples;
}
- void addDeltas(const RateAccumulator<T>& start, const RateAccumulator<T>& finish)
- {
- mSum += finish.mSum - start.mSum;
- mNumSamples += finish.mNumSamples - start.mNumSamples;
- }
-
void reset()
{
mNumSamples = 0;
@@ -464,13 +456,6 @@ namespace LLTrace
mCalls += other.mCalls;
}
- void addDeltas(const TimerAccumulator& start, const TimerAccumulator& finish)
- {
- mTotalTimeCounter += finish.mTotalTimeCounter - start.mTotalTimeCounter;
- mChildTimeCounter += finish.mChildTimeCounter - start.mChildTimeCounter;
- mCalls += finish.mCalls - start.mCalls;
- }
-
void reset()
{
mTotalTimeCounter = 0;
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 0883930319..5d7b231b7d 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -68,16 +68,16 @@ void Recording::handleReset()
}
void Recording::handleStart()
- {
- mSamplingTimer.reset();
- LLTrace::get_thread_recorder()->activate(this);
+{
+ mSamplingTimer.reset();
+ LLTrace::get_thread_recorder()->activate(this);
}
void Recording::handleStop()
- {
- mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
- LLTrace::get_thread_recorder()->deactivate(this);
- }
+{
+ mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
+ LLTrace::get_thread_recorder()->deactivate(this);
+}
void Recording::handleSplitTo(Recording& other)
{
@@ -105,10 +105,204 @@ void Recording::mergeRecording( const Recording& other )
mStackTimers.write()->addSamples(*other.mStackTimers);
}
-void Recording::mergeRecordingDelta(const Recording& baseline, const Recording& target)
+///////////////////////////////////////////////////////////////////////
+// Recording
+///////////////////////////////////////////////////////////////////////
+
+PeriodicRecording::PeriodicRecording( S32 num_periods )
+: mNumPeriods(num_periods),
+ mCurPeriod(0),
+ mTotalValid(false),
+ mRecordingPeriods( new Recording[num_periods])
+{
+ llassert(mNumPeriods > 0);
+}
+
+PeriodicRecording::~PeriodicRecording()
+{
+ delete[] mRecordingPeriods;
+}
+
+
+void PeriodicRecording::nextPeriod()
+{
+ EPlayState play_state = getPlayState();
+ getCurRecordingPeriod().stop();
+ mCurPeriod = (mCurPeriod + 1) % mNumPeriods;
+ switch(play_state)
+ {
+ case STOPPED:
+ break;
+ case PAUSED:
+ getCurRecordingPeriod().pause();
+ break;
+ case STARTED:
+ getCurRecordingPeriod().start();
+ break;
+ }
+ // new period, need to recalculate total
+ mTotalValid = false;
+}
+
+Recording& PeriodicRecording::getTotalRecording()
+{
+ if (!mTotalValid)
+ {
+ mTotalRecording.reset();
+ for (S32 i = (mCurPeriod + 1) % mNumPeriods; i < mCurPeriod; i++)
+ {
+ mTotalRecording.mergeRecording(mRecordingPeriods[i]);
+ }
+ }
+ mTotalValid = true;
+ return mTotalRecording;
+}
+
+void PeriodicRecording::handleStart()
+{
+ getCurRecordingPeriod().handleStart();
+}
+
+void PeriodicRecording::handleStop()
+{
+ getCurRecordingPeriod().handleStop();
+}
+
+void PeriodicRecording::handleReset()
+{
+ getCurRecordingPeriod().handleReset();
+}
+
+void PeriodicRecording::handleSplitTo( PeriodicRecording& other )
+{
+ getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod());
+}
+
+///////////////////////////////////////////////////////////////////////
+// ExtendableRecording
+///////////////////////////////////////////////////////////////////////
+
+void ExtendableRecording::extend()
{
- mRates.write()->addDeltas(*baseline.mRates, *target.mRates);
- mStackTimers.write()->addDeltas(*baseline.mStackTimers, *target.mStackTimers);
+ mAcceptedRecording.mergeRecording(mPotentialRecording);
+ mPotentialRecording.reset();
}
+void ExtendableRecording::handleStart()
+{
+ mPotentialRecording.handleStart();
+}
+
+void ExtendableRecording::handleStop()
+{
+ mPotentialRecording.handleStop();
+}
+
+void ExtendableRecording::handleReset()
+{
+ mAcceptedRecording.handleReset();
+ mPotentialRecording.handleReset();
+}
+
+void ExtendableRecording::handleSplitTo( ExtendableRecording& other )
+{
+ mPotentialRecording.handleSplitTo(other.mPotentialRecording);
+}
+
+PeriodicRecording& get_frame_recording()
+{
+ static PeriodicRecording sRecording(64);
+ sRecording.start();
+ return sRecording;
+}
+
+}
+
+void LLVCRControlsMixinCommon::start()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ handleReset();
+ handleStart();
+ break;
+ case PAUSED:
+ handleStart();
+ break;
+ case STARTED:
+ handleReset();
+ break;
+ }
+ mPlayState = STARTED;
+}
+
+void LLVCRControlsMixinCommon::stop()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ break;
+ case PAUSED:
+ handleStop();
+ break;
+ case STARTED:
+ handleStop();
+ break;
+ }
+ mPlayState = STOPPED;
+}
+
+void LLVCRControlsMixinCommon::pause()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ break;
+ case PAUSED:
+ break;
+ case STARTED:
+ handleStop();
+ break;
+ }
+ mPlayState = PAUSED;
+}
+
+void LLVCRControlsMixinCommon::resume()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ handleStart();
+ break;
+ case PAUSED:
+ handleStart();
+ break;
+ case STARTED:
+ break;
+ }
+ mPlayState = STARTED;
+}
+
+void LLVCRControlsMixinCommon::restart()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ handleReset();
+ handleStart();
+ break;
+ case PAUSED:
+ handleReset();
+ handleStart();
+ break;
+ case STARTED:
+ handleReset();
+ break;
+ }
+ mPlayState = STARTED;
+}
+
+void LLVCRControlsMixinCommon::reset()
+{
+ handleReset();
}
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 0a1a02fa02..924a7bffd5 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -34,27 +34,11 @@
#include "lltimer.h"
#include "lltrace.h"
-template<typename DERIVED>
-class LL_COMMON_API LLVCRControlsMixinInterface
+class LL_COMMON_API LLVCRControlsMixinCommon
{
public:
- virtual ~LLVCRControlsMixinInterface() {}
- // trigger data accumulation (without reset)
- virtual void handleStart() = 0;
- // stop data accumulation, should put object in queryable state
- virtual void handleStop() = 0;
- // clear accumulated values, can be called while started
- virtual void handleReset() = 0;
- // atomically stop this object while starting the other
- // no data can be missed in between stop and start
- virtual void handleSplitTo(DERIVED& other) = 0;
-};
+ virtual ~LLVCRControlsMixinCommon() {}
-template<typename DERIVED>
-class LL_COMMON_API LLVCRControlsMixin
-: private LLVCRControlsMixinInterface<DERIVED>
-{
-public:
enum EPlayState
{
STOPPED,
@@ -62,94 +46,39 @@ public:
STARTED
};
- void start()
- {
- switch (mPlayState)
- {
- case STOPPED:
- handleReset();
- handleStart();
- break;
- case PAUSED:
- handleStart();
- break;
- case STARTED:
- handleReset();
- break;
- }
- mPlayState = STARTED;
- }
+ void start();
+ void stop();
+ void pause();
+ void resume();
+ void restart();
+ void reset();
- void stop()
- {
- switch (mPlayState)
- {
- case STOPPED:
- break;
- case PAUSED:
- handleStop();
- break;
- case STARTED:
- break;
- }
- mPlayState = STOPPED;
- }
-
- void pause()
- {
- switch (mPlayState)
- {
- case STOPPED:
- break;
- case PAUSED:
- break;
- case STARTED:
- handleStop();
- break;
- }
- mPlayState = PAUSED;
- }
+ bool isStarted() { return mPlayState == STARTED; }
+ bool isPaused() { return mPlayState == PAUSED; }
+ bool isStopped() { return mPlayState == STOPPED; }
+ EPlayState getPlayState() { return mPlayState; }
- void resume()
- {
- switch (mPlayState)
- {
- case STOPPED:
- handleStart();
- break;
- case PAUSED:
- handleStart();
- break;
- case STARTED:
- break;
- }
- mPlayState = STARTED;
- }
+protected:
+ LLVCRControlsMixinCommon()
+ : mPlayState(STOPPED)
+ {}
- void restart()
- {
- switch (mPlayState)
- {
- case STOPPED:
- handleReset();
- handleStart();
- break;
- case PAUSED:
- handleReset();
- handleStart();
- break;
- case STARTED:
- handleReset();
- break;
- }
- mPlayState = STARTED;
- }
+private:
+ // trigger data accumulation (without reset)
+ virtual void handleStart() = 0;
+ // stop data accumulation, should put object in queryable state
+ virtual void handleStop() = 0;
+ // clear accumulated values, can be called while started
+ virtual void handleReset() = 0;
- void reset()
- {
- handleReset();
- }
+ EPlayState mPlayState;
+};
+template<typename DERIVED>
+class LLVCRControlsMixin
+: public LLVCRControlsMixinCommon
+{
+public:
void splitTo(DERIVED& other)
{
onSplitTo(other);
@@ -159,32 +88,15 @@ public:
{
other.onSplitTo(*this);
}
-
- bool isStarted() { return mPlayState == STARTED; }
- bool isPaused() { return mPlayState == PAUSED; }
- bool isStopped() { return mPlayState == STOPPED; }
- EPlayState getPlayState() { return mPlayState; }
-
-protected:
-
- LLVCRControlsMixin()
- : mPlayState(STOPPED)
- {}
-
private:
- EPlayState mPlayState;
+ // atomically stop this object while starting the other
+ // no data can be missed in between stop and start
+ virtual void handleSplitTo(DERIVED& other) = 0;
+
};
namespace LLTrace
{
- //template<typename T, typename IS_UNIT> class Rate;
- //template<typename T, typename IS_UNIT> class Measurement;
- //template<typename T> class Count;
- //template<typename T> class AccumulatorBuffer;
- //template<typename T> class RateAccumulator;
- //template<typename T> class MeasurementAccumulator;
- //class TimerAccumulator;
-
class LL_COMMON_API Recording : public LLVCRControlsMixin<Recording>
{
public:
@@ -196,7 +108,6 @@ namespace LLTrace
bool isPrimary() const;
void mergeRecording(const Recording& other);
- void mergeRecordingDelta(const Recording& baseline, const Recording& target);
void update();
@@ -308,15 +219,13 @@ namespace LLTrace
F64 getSampleTime() const { return mElapsedSeconds; }
- private:
- friend class PeriodicRecording;
// implementation for LLVCRControlsMixin
/*virtual*/ void handleStart();
/*virtual*/ void handleStop();
/*virtual*/ void handleReset();
/*virtual*/ void handleSplitTo(Recording& other);
-
+ private:
friend class ThreadRecorder;
// returns data for current thread
class ThreadRecorder* getThreadRecorder();
@@ -333,38 +242,19 @@ namespace LLTrace
: public LLVCRControlsMixin<PeriodicRecording>
{
public:
- PeriodicRecording(S32 num_periods)
- : mNumPeriods(num_periods),
- mCurPeriod(0),
- mTotalValid(false),
- mRecordingPeriods(new Recording[num_periods])
- {
- llassert(mNumPeriods > 0);
- }
+ PeriodicRecording(S32 num_periods);
+ ~PeriodicRecording();
+
+ void nextPeriod();
- ~PeriodicRecording()
+ Recording& getLastRecordingPeriod()
{
- delete[] mRecordingPeriods;
+ return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods];
}
- void nextPeriod()
+ const Recording& getLastRecordingPeriod() const
{
- EPlayState play_state = getPlayState();
- getCurRecordingPeriod().stop();
- mCurPeriod = (mCurPeriod + 1) % mNumPeriods;
- switch(play_state)
- {
- case STOPPED:
- break;
- case PAUSED:
- getCurRecordingPeriod().pause();
- break;
- case STARTED:
- getCurRecordingPeriod().start();
- break;
- }
- // new period, need to recalculate total
- mTotalValid = false;
+ return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods];
}
Recording& getCurRecordingPeriod()
@@ -377,41 +267,16 @@ namespace LLTrace
return mRecordingPeriods[mCurPeriod];
}
- Recording& getTotalRecording()
- {
- if (!mTotalValid)
- {
- mTotalRecording.reset();
- for (S32 i = (mCurPeriod + 1) % mNumPeriods; i < mCurPeriod; i++)
- {
- mTotalRecording.mergeRecording(mRecordingPeriods[i]);
- }
- }
- mTotalValid = true;
- return mTotalRecording;
- }
+ Recording& getTotalRecording();
private:
- // implementation for LLVCRControlsMixin
- /*virtual*/ void handleStart()
- {
- getCurRecordingPeriod().handleStart();
- }
-
- /*virtual*/ void handleStop()
- {
- getCurRecordingPeriod().handleStop();
- }
- /*virtual*/ void handleReset()
- {
- getCurRecordingPeriod().handleReset();
- }
+ // implementation for LLVCRControlsMixin
+ /*virtual*/ void handleStart();
+ /*virtual*/ void handleStop();
+ /*virtual*/ void handleReset();
- /*virtual*/ void handleSplitTo(PeriodicRecording& other)
- {
- getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod());
- }
+ /*virtual*/ void handleSplitTo(PeriodicRecording& other);
Recording* mRecordingPeriods;
Recording mTotalRecording;
@@ -419,6 +284,24 @@ namespace LLTrace
S32 mNumPeriods,
mCurPeriod;
};
+
+ PeriodicRecording& get_frame_recording();
+
+ class ExtendableRecording
+ : public LLVCRControlsMixin<ExtendableRecording>
+ {
+ void extend();
+
+ private:
+ // implementation for LLVCRControlsMixin
+ /*virtual*/ void handleStart();
+ /*virtual*/ void handleStop();
+ /*virtual*/ void handleReset();
+ /*virtual*/ void handleSplitTo(ExtendableRecording& other);
+
+ Recording mAcceptedRecording;
+ Recording mPotentialRecording;
+ };
}
#endif // LL_LLTRACERECORDING_H
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 3acd06d553..48aa1a42f2 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -36,15 +36,13 @@ namespace LLTrace
///////////////////////////////////////////////////////////////////////
ThreadRecorder::ThreadRecorder()
-: mPrimaryRecording(NULL)
{
get_thread_recorder() = this;
mFullRecording.start();
}
ThreadRecorder::ThreadRecorder( const ThreadRecorder& other )
-: mFullRecording(other.mFullRecording),
- mPrimaryRecording(NULL)
+: mFullRecording(other.mFullRecording)
{
get_thread_recorder() = this;
mFullRecording.start();
@@ -55,45 +53,40 @@ ThreadRecorder::~ThreadRecorder()
get_thread_recorder() = NULL;
}
-//TODO: remove this and use llviewerstats recording
-Recording* ThreadRecorder::getPrimaryRecording()
-{
- return mPrimaryRecording;
-}
-
void ThreadRecorder::activate( Recording* recording )
{
- mActiveRecordings.push_front(ActiveRecording(mPrimaryRecording, recording));
+ mActiveRecordings.push_front(ActiveRecording(recording));
mActiveRecordings.front().mBaseline.makePrimary();
- mPrimaryRecording = &mActiveRecordings.front().mBaseline;
}
std::list<ThreadRecorder::ActiveRecording>::iterator ThreadRecorder::update( Recording* recording )
{
- for (std::list<ActiveRecording>::iterator it = mActiveRecordings.begin(), end_it = mActiveRecordings.end();
+ std::list<ActiveRecording>::iterator it, end_it;
+ for (it = mActiveRecordings.begin(), end_it = mActiveRecordings.end();
it != end_it;
++it)
{
std::list<ActiveRecording>::iterator next_it = it;
- if (++next_it != mActiveRecordings.end())
+ ++next_it;
+
+ // if we have another recording further down in the stack...
+ if (next_it != mActiveRecordings.end())
{
- next_it->mergeMeasurements((*it));
+ // ...push our gathered data down to it
+ next_it->mBaseline.mergeRecording(it->mBaseline);
}
- it->flushAccumulators(mPrimaryRecording);
+ // copy accumulated measurements into result buffer and clear accumulator (mBaseline)
+ it->moveBaselineToTarget();
if (it->mTargetRecording == recording)
{
- if (next_it != mActiveRecordings.end())
- {
- next_it->mBaseline.makePrimary();
- mPrimaryRecording = &next_it->mBaseline;
- }
- return it;
+ // found the recording, so return it
+ break;
}
}
- return mActiveRecordings.end();
+ return it;
}
void ThreadRecorder::deactivate( Recording* recording )
@@ -101,38 +94,34 @@ void ThreadRecorder::deactivate( Recording* recording )
std::list<ActiveRecording>::iterator it = update(recording);
if (it != mActiveRecordings.end())
{
+ // and if we've found the recording we wanted to update
+ std::list<ActiveRecording>::iterator next_it = it;
+ ++next_it;
+ if (next_it != mActiveRecordings.end())
+ {
+ next_it->mTargetRecording->makePrimary();
+ }
+
mActiveRecordings.erase(it);
}
}
-ThreadRecorder::ActiveRecording::ActiveRecording( Recording* source, Recording* target )
+ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target )
: mTargetRecording(target)
{
- // take snapshots of current values rates and timers
- if (source)
- {
- mBaseline.mRates.write()->copyFrom(*source->mRates);
- mBaseline.mStackTimers.write()->copyFrom(*source->mStackTimers);
- }
}
-void ThreadRecorder::ActiveRecording::mergeMeasurements(ThreadRecorder::ActiveRecording& other)
+void ThreadRecorder::ActiveRecording::moveBaselineToTarget()
{
- mBaseline.mMeasurements.write()->addSamples(*other.mBaseline.mMeasurements);
-}
-
-void ThreadRecorder::ActiveRecording::flushAccumulators(Recording* current)
-{
- // accumulate statistics-like measurements
mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements);
- // for rate-like measurements, merge total change since baseline
- mTargetRecording->mRates.write()->addDeltas(*mBaseline.mRates, *current->mRates);
- mTargetRecording->mStackTimers.write()->addDeltas(*mBaseline.mStackTimers, *current->mStackTimers);
- // reset baselines
- mBaseline.mRates.write()->copyFrom(*current->mRates);
- mBaseline.mStackTimers.write()->copyFrom(*current->mStackTimers);
+ mTargetRecording->mRates.write()->addSamples(*mBaseline.mRates);
+ mTargetRecording->mStackTimers.write()->addSamples(*mBaseline.mStackTimers);
+ mBaseline.mMeasurements.write()->reset();
+ mBaseline.mRates.write()->reset();
+ mBaseline.mStackTimers.write()->reset();
}
+
///////////////////////////////////////////////////////////////////////
// SlaveThreadRecorder
///////////////////////////////////////////////////////////////////////
diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h
index 42230087c0..678b1a89f0 100644
--- a/indra/llcommon/lltracethreadrecorder.h
+++ b/indra/llcommon/lltracethreadrecorder.h
@@ -51,19 +51,16 @@ namespace LLTrace
virtual void pushToMaster() = 0;
- Recording* getPrimaryRecording();
protected:
struct ActiveRecording
{
- ActiveRecording(Recording* source, Recording* target);
+ ActiveRecording(Recording* target);
Recording* mTargetRecording;
Recording mBaseline;
- void mergeMeasurements(ActiveRecording& other);
- void flushAccumulators(Recording* current);
+ void moveBaselineToTarget();
};
- Recording* mPrimaryRecording;
Recording mFullRecording;
std::list<ActiveRecording> mActiveRecordings;
};