diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/lldefs.h | 48 | ||||
-rw-r--r-- | indra/llcommon/llmd5.cpp | 32 | ||||
-rw-r--r-- | indra/llcommon/llmd5.h | 23 | ||||
-rw-r--r-- | indra/llcommon/llsdserialize.cpp | 2 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.cpp | 124 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.h | 172 | ||||
-rw-r--r-- | indra/llcommon/tests/llsdserialize_test.cpp | 2 |
7 files changed, 201 insertions, 202 deletions
diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index 5c46f6a796..4e25001fff 100644 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h @@ -167,48 +167,34 @@ const U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 + 1 for good luc // // defined for U16, U32, U64, S16, S32, S64, : // llclampb(a) // clamps a to [0 .. 255] -// - -template <typename T1, typename T2> -inline auto llmax(T1 d1, T2 d2) -{ - return (d1 > d2) ? d1 : d2; -} - -template <typename T1, typename T2, typename T3> -inline auto llmax(T1 d1, T2 d2, T3 d3) -{ - auto r = llmax(d1,d2); - return llmax(r, d3); -} +// -template <typename T1, typename T2, typename T3, typename T4> -inline auto llmax(T1 d1, T2 d2, T3 d3, T4 d4) +// recursion tail +template <typename T> +inline auto llmax(T data) { - auto r1 = llmax(d1,d2); - auto r2 = llmax(d3,d4); - return llmax(r1, r2); + return data; } -template <typename T1, typename T2> -inline auto llmin(T1 d1, T2 d2) +template <typename T0, typename T1, typename... Ts> +inline auto llmax(T0 d0, T1 d1, Ts... rest) { - return (d1 < d2) ? d1 : d2; + auto maxrest = llmax(d1, rest...); + return (d0 > maxrest)? d0 : maxrest; } -template <typename T1, typename T2, typename T3> -inline auto llmin(T1 d1, T2 d2, T3 d3) +// recursion tail +template <typename T> +inline auto llmin(T data) { - auto r = llmin(d1,d2); - return (r < d3 ? r : d3); + return data; } -template <typename T1, typename T2, typename T3, typename T4> -inline auto llmin(T1 d1, T2 d2, T3 d3, T4 d4) +template <typename T0, typename T1, typename... Ts> +inline auto llmin(T0 d0, T1 d1, Ts... rest) { - auto r1 = llmin(d1,d2); - auto r2 = llmin(d3,d4); - return llmin(r1, r2); + auto minrest = llmin(d1, rest...); + return (d0 < minrest) ? d0 : minrest; } template <typename A, typename MIN, typename MAX> diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index 9b2a2bab60..0abe817f1d 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -96,7 +96,7 @@ LLMD5::LLMD5() // operation, processing another message block, and updating the // context. -void LLMD5::update (const uint1 *input, const size_t input_length) { +void LLMD5::update (const uint8_t *input, const size_t input_length) { size_t input_index, buffer_index; size_t buffer_space; // how much space is left in buffer @@ -189,7 +189,7 @@ void LLMD5::finalize (){ unsigned char bits[8]; /* Flawfinder: ignore */ size_t index, padLen; - static uint1 PADDING[64]={ + static uint8_t PADDING[64]={ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -201,8 +201,8 @@ void LLMD5::finalize (){ } // Save number of bits. - // Treat count, a uint64_t, as uint4[2]. - encode (bits, reinterpret_cast<uint4*>(&count), 8); + // Treat count, a uint64_t, as uint32_t[2]. + encode (bits, reinterpret_cast<uint32_t*>(&count), 8); // Pad out to 56 mod 64. index = size_t((count >> 3) & 0x3f); @@ -412,7 +412,7 @@ Rotation is separate from addition to prevent recomputation. // LLMD5 basic transformation. Transforms state based on block. void LLMD5::transform (const U8 block[64]){ - uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; decode (x, block, 64); @@ -496,38 +496,38 @@ void LLMD5::transform (const U8 block[64]){ state[3] += d; // Zeroize sensitive information. - memset ( (uint1 *) x, 0, sizeof(x)); + memset ( (uint8_t *) x, 0, sizeof(x)); } -// Encodes input (UINT4) into output (unsigned char). Assumes len is +// Encodes input (uint32_t) into output (unsigned char). Assumes len is // a multiple of 4. -void LLMD5::encode (uint1 *output, const uint4 *input, const size_t len) { +void LLMD5::encode (uint8_t *output, const uint32_t *input, const size_t len) { size_t i, j; for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (uint1) (input[i] & 0xff); - output[j+1] = (uint1) ((input[i] >> 8) & 0xff); - output[j+2] = (uint1) ((input[i] >> 16) & 0xff); - output[j+3] = (uint1) ((input[i] >> 24) & 0xff); + output[j] = (uint8_t) (input[i] & 0xff); + output[j+1] = (uint8_t) ((input[i] >> 8) & 0xff); + output[j+2] = (uint8_t) ((input[i] >> 16) & 0xff); + output[j+3] = (uint8_t) ((input[i] >> 24) & 0xff); } } -// Decodes input (unsigned char) into output (UINT4). Assumes len is +// Decodes input (unsigned char) into output (uint32_t). Assumes len is // a multiple of 4. -void LLMD5::decode (uint4 *output, const uint1 *input, const size_t len){ +void LLMD5::decode (uint32_t *output, const uint8_t *input, const size_t len){ size_t i, j; for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | - (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); + output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | + (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24); } diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index 8530dc0389..7d6373c20c 100644 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h @@ -67,6 +67,8 @@ documentation and/or software. */ +#include <cstdint> // uint32_t et al. + // use for the raw digest output const int MD5RAW_BYTES = 16; @@ -75,18 +77,13 @@ const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null const int MD5HEX_STR_BYTES = 32; // message system fixed size class LL_COMMON_API LLMD5 { -// first, some types: - typedef unsigned int uint4; // assumes integer is 4 words long - typedef unsigned short int uint2; // assumes short integer is 2 words long - typedef unsigned char uint1; // assumes char is 1 word long - // how many bytes to grab at a time when checking files static const int BLOCK_LEN; public: // methods for controlled operation: LLMD5 (); // simple initializer - void update (const uint1 *input, const size_t input_length); + void update (const uint8_t *input, const size_t input_length); void update (std::istream& stream); void update (FILE *file); void update (const std::string& str); @@ -109,19 +106,19 @@ private: // next, the private data: - uint4 state[4]; + uint32_t state[4]; uint64_t count; // number of *bits*, mod 2^64 - uint1 buffer[64]; // input buffer - uint1 digest[16]; - uint1 finalized; + uint8_t buffer[64]; // input buffer + uint8_t digest[16]; + uint8_t finalized; // last, the private methods, mostly static: void init (); // called by all constructors - void transform (const uint1 *buffer); // does the real update work. Note + void transform (const uint8_t *buffer); // does the real update work. Note // that length is implied to be 64. - static void encode (uint1 *dest, const uint4 *src, const size_t length); - static void decode (uint4 *dest, const uint1 *src, const size_t length); + static void encode (uint8_t *dest, const uint32_t *src, const size_t length); + static void decode (uint32_t *dest, const uint8_t *src, const size_t length); }; diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index a14a6b5b1b..046523dbb1 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -143,7 +143,7 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, llssize max_bytes) // byte. We could store one if needed, since even the incremented // inbuf won't exceed sizeof(hdr_buf)-1, but there's no need. } - std::string header{ hdr_buf, inbuf }; + std::string header{ hdr_buf, static_cast<std::string::size_type>(inbuf) }; if (str.fail()) { str.clear(); diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index a8dcc5226a..bb3d667a42 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -577,10 +577,12 @@ S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat ) // PeriodicRecording /////////////////////////////////////////////////////////////////////// -PeriodicRecording::PeriodicRecording( S32 num_periods, EPlayState state) +PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state) : mAutoResize(num_periods == 0), mCurPeriod(0), mNumRecordedPeriods(0), + // This guarantee that mRecordingPeriods cannot be empty is essential for + // code in several methods. mRecordingPeriods(num_periods ? num_periods : 1) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; @@ -596,18 +598,19 @@ PeriodicRecording::~PeriodicRecording() void PeriodicRecording::nextPeriod() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (mAutoResize) { mRecordingPeriods.push_back(Recording()); } Recording& old_recording = getCurRecording(); - mCurPeriod = (mCurPeriod + 1) % mRecordingPeriods.size(); + inci(mCurPeriod); old_recording.splitTo(getCurRecording()); - mNumRecordedPeriods = mRecordingPeriods.empty()? 0 : - llmin(mRecordingPeriods.size() - 1, mNumRecordedPeriods + 1); + // Since mRecordingPeriods always has at least one entry, we can always + // safely subtract 1 from its size(). + mNumRecordedPeriods = llmin(mRecordingPeriods.size() - 1, mNumRecordedPeriods + 1); } void PeriodicRecording::appendRecording(Recording& recording) @@ -620,31 +623,29 @@ void PeriodicRecording::appendRecording(Recording& recording) void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (other.mRecordingPeriods.empty()) return; getCurRecording().update(); other.getCurRecording().update(); - - const auto other_recording_slots = other.mRecordingPeriods.size(); + const auto other_num_recordings = other.getNumRecordedPeriods(); const auto other_current_recording_index = other.mCurPeriod; - const auto other_oldest_recording_index = (other_current_recording_index + other_recording_slots - other_num_recordings) % other_recording_slots; + const auto other_oldest_recording_index = other.previ(other_current_recording_index, other_num_recordings); // append first recording into our current slot getCurRecording().appendRecording(other.mRecordingPeriods[other_oldest_recording_index]); // from now on, add new recordings for everything after the first - auto other_index = (other_oldest_recording_index + 1) % other_recording_slots; + auto other_index = other.nexti(other_oldest_recording_index); if (mAutoResize) { // push back recordings for everything in the middle - auto other_index = (other_oldest_recording_index + 1) % other_recording_slots; while (other_index != other_current_recording_index) { mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]); - other_index = (other_index + 1) % other_recording_slots; + other.inci(other_index); } // add final recording, if it wasn't already added as the first @@ -653,36 +654,25 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) mRecordingPeriods.push_back(other.mRecordingPeriods[other_current_recording_index]); } - mCurPeriod = mRecordingPeriods.empty()? 0 : mRecordingPeriods.size() - 1; + // mRecordingPeriods is never empty() + mCurPeriod = mRecordingPeriods.size() - 1; mNumRecordedPeriods = mCurPeriod; } else { - S32 num_to_copy = llmin((S32)mRecordingPeriods.size(), (S32)other_num_recordings); - - std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin() + other_index ; - std::vector<Recording>::iterator dest_it = mRecordingPeriods.begin() + mCurPeriod; - + auto num_to_copy = llmin(mRecordingPeriods.size(), other_num_recordings); // already consumed the first recording from other, so start counting at 1 - for(S32 i = 1; i < num_to_copy; i++) + for (size_t n = 1, srci = other_index, dsti = mCurPeriod; + n < num_to_copy; + ++n, other.inci(srci), inci(dsti)) { - *dest_it = *src_it; - - if (++src_it == other.mRecordingPeriods.end()) - { - src_it = other.mRecordingPeriods.begin(); - } - - if (++dest_it == mRecordingPeriods.end()) - { - dest_it = mRecordingPeriods.begin(); - } + mRecordingPeriods[dsti] = other.mRecordingPeriods[srci]; } - + // want argument to % to be positive, otherwise result could be negative and thus out of bounds llassert(num_to_copy >= 1); // advance to last recording period copied, and make that our current period - mCurPeriod = (mCurPeriod + num_to_copy - 1) % mRecordingPeriods.size(); + inci(mCurPeriod, num_to_copy - 1); mNumRecordedPeriods = llmin(mRecordingPeriods.size() - 1, mNumRecordedPeriods + num_to_copy - 1); } @@ -694,13 +684,11 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) F64Seconds PeriodicRecording::getDuration() const { - LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; F64Seconds duration; - auto num_periods = mRecordingPeriods.size(); - for (size_t i = 1; i <= num_periods; i++) + for (size_t n = 0; n < mRecordingPeriods.size(); ++n) { - auto index = (mCurPeriod + num_periods - i) % num_periods; - duration += mRecordingPeriods[index].getDuration(); + duration += mRecordingPeriods[nexti(mCurPeriod, n)].getDuration(); } return duration; } @@ -737,16 +725,14 @@ const Recording& PeriodicRecording::getCurRecording() const Recording& PeriodicRecording::getPrevRecording( size_t offset ) { - auto num_periods = mRecordingPeriods.size(); - offset = llclamp(offset, 0, num_periods - 1); - return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods]; + // reuse const implementation, but return non-const reference + return const_cast<Recording&>( + const_cast<const PeriodicRecording*>(this)->getPrevRecording(offset)); } const Recording& PeriodicRecording::getPrevRecording( size_t offset ) const { - auto num_periods = mRecordingPeriods.size(); - offset = llclamp(offset, 0, num_periods - 1); - return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods]; + return mRecordingPeriods[previ(mCurPeriod, offset)]; } void PeriodicRecording::handleStart() @@ -789,14 +775,14 @@ void PeriodicRecording::handleSplitTo(PeriodicRecording& other) getCurRecording().splitTo(other.getCurRecording()); } -F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; F64 min_val = std::numeric_limits<F64>::max(); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -811,14 +797,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, siz : NaN; } -F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; F64 max_val = std::numeric_limits<F64>::min(); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -834,7 +820,7 @@ F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, siz } // calculates means using aggregates per period -F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -842,7 +828,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, si F64 mean = 0; S32 valid_period_count = 0; - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -857,7 +843,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, si : NaN; } -F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -866,7 +852,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat F64 sum_of_squares = 0; S32 valid_period_count = 0; - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -882,14 +868,14 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat : NaN; } -F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; F64 min_val = std::numeric_limits<F64>::max(); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -904,14 +890,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, si : NaN; } -F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/) +F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; F64 max_val = std::numeric_limits<F64>::min(); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -927,7 +913,7 @@ F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, siz } -F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -935,7 +921,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, s S32 valid_period_count = 0; F64 mean = 0; - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -950,13 +936,13 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, s : NaN; } -F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); std::vector<F64> buf; - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.getDuration() > (F32Seconds)0.f) @@ -976,7 +962,7 @@ F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, return F64((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]); } -F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -985,7 +971,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula S32 valid_period_count = 0; F64 sum_of_squares = 0; - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -1002,13 +988,13 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula } -F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64Kilobytes min_val(std::numeric_limits<F64>::max()); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); min_val = llmin(min_val, recording.getMin(stat)); @@ -1022,13 +1008,13 @@ F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, size_t n return getPeriodMin(static_cast<const StatType<MemAccumulator>&>(stat), num_periods); } -F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/) +F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64Kilobytes max_val(0.0); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); max_val = llmax(max_val, recording.getMax(stat)); @@ -1042,14 +1028,14 @@ F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, size_t n return getPeriodMax(static_cast<const StatType<MemAccumulator>&>(stat), num_periods); } -F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64Kilobytes mean(0); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); mean += recording.getMean(stat); @@ -1063,7 +1049,7 @@ F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, size_t return getPeriodMean(static_cast<const StatType<MemAccumulator>&>(stat), num_periods); } -F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) +F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -1072,7 +1058,7 @@ F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAc S32 valid_period_count = 0; F64 sum_of_squares = 0; - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 8b56721f42..a6b1a67d02 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -33,6 +33,7 @@ #include "lltimer.h" #include "lltraceaccumulators.h" #include "llpointer.h" +#include <limits> class LLStopWatchControlsMixinCommon { @@ -330,7 +331,7 @@ namespace LLTrace : public LLStopWatchControlsMixin<PeriodicRecording> { public: - PeriodicRecording(S32 num_periods, EPlayState state = STOPPED); + PeriodicRecording(size_t num_periods, EPlayState state = STOPPED); ~PeriodicRecording(); void nextPeriod(); @@ -353,7 +354,7 @@ namespace LLTrace Recording snapshotCurRecording() const; template <typename T> - auto getSampleCount(const StatType<T>& stat, size_t num_periods = S32_MAX) + auto getSampleCount(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -373,14 +374,14 @@ namespace LLTrace // catch all for stats that have a defined sum template <typename T> - typename T::value_t getPeriodMin(const StatType<T>& stat, size_t num_periods = S32_MAX) + typename T::value_t getPeriodMin(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; typename T::value_t min_val(std::numeric_limits<typename T::value_t>::max()); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -396,39 +397,39 @@ namespace LLTrace } template<typename T> - T getPeriodMin(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) + T getPeriodMin(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } - F64 getPeriodMin(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodMin(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template<typename T> - T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX) + T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } - F64 getPeriodMin(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodMin(const StatType<EventAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template<typename T> - T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX) + T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } - F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX); - F64Kilobytes getPeriodMin(const MemStatHandle& stat, size_t num_periods = S32_MAX); + F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); + F64Kilobytes getPeriodMin(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); typename RelatedTypes<typename T::value_t>::fractional_t min_val(std::numeric_limits<F64>::max()); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); min_val = llmin(min_val, recording.getPerSec(stat)); @@ -437,7 +438,7 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMinPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); @@ -449,14 +450,14 @@ namespace LLTrace // catch all for stats that have a defined sum template <typename T> - typename T::value_t getPeriodMax(const StatType<T>& stat, size_t num_periods = S32_MAX) + typename T::value_t getPeriodMax(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; typename T::value_t max_val(std::numeric_limits<typename T::value_t>::min()); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.hasValue(stat)) @@ -472,39 +473,39 @@ namespace LLTrace } template<typename T> - T getPeriodMax(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) + T getPeriodMax(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } - F64 getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template<typename T> - T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX) + T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } - F64 getPeriodMax(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodMax(const StatType<EventAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template<typename T> - T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX) + T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } - F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX); - F64Kilobytes getPeriodMax(const MemStatHandle& stat, size_t num_periods = S32_MAX); + F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); + F64Kilobytes getPeriodMax(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64 max_val = std::numeric_limits<F64>::min(); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); max_val = llmax(max_val, recording.getPerSec(stat)); @@ -513,7 +514,7 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMaxPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); @@ -525,14 +526,14 @@ namespace LLTrace // catch all for stats that have a defined sum template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); typename RelatedTypes<typename T::value_t>::fractional_t mean(0); - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.getDuration() > (F32Seconds)0.f) @@ -546,39 +547,39 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } - F64 getPeriodMean(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodMean(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } - F64 getPeriodMean(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodMean(const StatType<EventAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } - F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX); - F64Kilobytes getPeriodMean(const MemStatHandle& stat, size_t num_periods = S32_MAX); + F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); + F64Kilobytes getPeriodMean(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); typename RelatedTypes<typename T::value_t>::fractional_t mean = 0; - for (S32 i = 1; i <= num_periods; i++) + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); if (recording.getDuration() > (F32Seconds)0.f) @@ -593,64 +594,64 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } - F64 getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); - template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - num_periods = llmin(num_periods, getNumRecordedPeriods()); - - std::vector <typename RelatedTypes<typename T::value_t>::fractional_t> buf; - for (S32 i = 1; i <= num_periods; i++) - { - Recording& recording = getPrevRecording(i); - if (recording.getDuration() > (F32Seconds)0.f) - { - buf.push_back(recording.getPerSec(stat)); - } - } - std::sort(buf.begin(), buf.end()); - - return typename RelatedTypes<T>::fractional_t((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]); - } - - template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - return typename RelatedTypes<T>::fractional_t(getPeriodMedianPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); - } + template <typename T> + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + num_periods = llmin(num_periods, getNumRecordedPeriods()); + + std::vector <typename RelatedTypes<typename T::value_t>::fractional_t> buf; + for (size_t i = 1; i <= num_periods; i++) + { + Recording& recording = getPrevRecording(i); + if (recording.getDuration() > (F32Seconds)0.f) + { + buf.push_back(recording.getPerSec(stat)); + } + } + std::sort(buf.begin(), buf.end()); + + return typename RelatedTypes<T>::fractional_t((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]); + } + + template<typename T> + typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + return typename RelatedTypes<T>::fractional_t(getPeriodMedianPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); + } // // PERIODIC STANDARD DEVIATION // - F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } - F64 getPeriodStandardDeviation(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX); + F64 getPeriodStandardDeviation(const StatType<EventAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } - F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX); - F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods = S32_MAX); + F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max()); + F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max()); private: // implementation for LLStopWatchControlsMixin @@ -659,6 +660,35 @@ namespace LLTrace /*virtual*/ void handleReset(); /*virtual*/ void handleSplitTo(PeriodicRecording& other); + // helper methods for wraparound ring-buffer arithmetic + inline + size_t wrapi(size_t i) const + { + return i % mRecordingPeriods.size(); + } + + inline + size_t nexti(size_t i, size_t offset=1) const + { + return wrapi(i + offset); + } + + inline + size_t previ(size_t i, size_t offset=1) const + { + auto num_periods = mRecordingPeriods.size(); + // constrain offset + offset = llclamp(offset, 0, num_periods - 1); + // add size() so expression can't go (unsigned) "negative" + return wrapi(i + num_periods - offset); + } + + inline + void inci(size_t& i, size_t offset=1) const + { + i = nexti(i, offset); + } + private: std::vector<Recording> mRecordingPeriods; const bool mAutoResize; diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp index 29e3007aff..618f33cc13 100644 --- a/indra/llcommon/tests/llsdserialize_test.cpp +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -276,7 +276,7 @@ namespace tut // why does LLSDSerialize::deserialize() reverse the parse() params?? mParser = [parser](std::istream& istr, LLSD& data, llssize max_bytes) { - return (parser(data, istr, max_bytes) > 0); + return parser(data, istr, max_bytes); }; } |