diff options
Diffstat (limited to 'src/unstable')
| -rw-r--r-- | src/unstable/speedometer.cpp | 120 | ||||
| -rw-r--r-- | src/unstable/speedometer.h | 43 |
2 files changed, 163 insertions, 0 deletions
diff --git a/src/unstable/speedometer.cpp b/src/unstable/speedometer.cpp new file mode 100644 index 0000000..75e424e --- /dev/null +++ b/src/unstable/speedometer.cpp | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | #include "bu/speedometer.h" | ||
| 2 | #include "bu/mutexlocker.h" | ||
| 3 | #include "bu/sio.h" | ||
| 4 | |||
| 5 | #include <sys/time.h> | ||
| 6 | #include <string.h> | ||
| 7 | |||
| 8 | Bu::Speedometer::Speedometer( int64_t iBucketMs, int32_t iBucketCount ) : | ||
| 9 | aiBucket( NULL ), | ||
| 10 | iTotal( 0 ), | ||
| 11 | iCapacity( iBucketCount ), | ||
| 12 | iFill( 0 ), | ||
| 13 | iStart( 0 ), | ||
| 14 | iCurrent( 0 ), | ||
| 15 | iBucketMs( iBucketMs ), | ||
| 16 | iStartTime( -1 ), | ||
| 17 | iWindowSizeMs( iBucketMs*iBucketCount ), | ||
| 18 | iLastUpdate( -1 ) | ||
| 19 | { | ||
| 20 | aiBucket = new uint32_t[iCapacity]; | ||
| 21 | memset( aiBucket, 0, sizeof(uint32_t)*iCapacity ); | ||
| 22 | } | ||
| 23 | |||
| 24 | Bu::Speedometer::~Speedometer() | ||
| 25 | { | ||
| 26 | delete[] aiBucket; | ||
| 27 | aiBucket = NULL; | ||
| 28 | } | ||
| 29 | |||
| 30 | void Bu::Speedometer::addEvent() | ||
| 31 | { | ||
| 32 | Bu::MutexLocker l( mLock ); | ||
| 33 | int64_t iNow = getCurrentTime(); | ||
| 34 | _updateBuckets( iNow ); | ||
| 35 | if( iStartTime < 0 ) | ||
| 36 | { | ||
| 37 | iStartTime = iNow; | ||
| 38 | iFill = 1; | ||
| 39 | aiBucket[iCurrent] = 1; | ||
| 40 | iTotal = 1; | ||
| 41 | } | ||
| 42 | else | ||
| 43 | { | ||
| 44 | aiBucket[iCurrent]++; | ||
| 45 | iTotal++; | ||
| 46 | } | ||
| 47 | iLastUpdate = iNow; | ||
| 48 | } | ||
| 49 | |||
| 50 | void Bu::Speedometer::debug() | ||
| 51 | { | ||
| 52 | Bu::MutexLocker l( mLock ); | ||
| 53 | Bu::print("%1 of %2: %3:%4: "). | ||
| 54 | arg( iFill ).arg( iCapacity ).arg( iStart ).arg( iCurrent ); | ||
| 55 | for( int j = 0; j < iFill; j++ ) | ||
| 56 | { | ||
| 57 | Bu::print("%1 | ").arg( aiBucket[(j+iStart)%iCapacity] ); | ||
| 58 | } | ||
| 59 | Bu::println(" total = %1").arg( iTotal ); | ||
| 60 | } | ||
| 61 | |||
| 62 | void Bu::Speedometer::_updateBuckets( int64_t iNow ) | ||
| 63 | { | ||
| 64 | if( iNow > iLastUpdate+iWindowSizeMs ) | ||
| 65 | { | ||
| 66 | iLastUpdate = iStartTime = -1; | ||
| 67 | iFill = 0; | ||
| 68 | iStart = iCurrent = 0; | ||
| 69 | aiBucket[iCurrent] = 0; | ||
| 70 | iTotal = 0; | ||
| 71 | } | ||
| 72 | else | ||
| 73 | { | ||
| 74 | int64_t iSkip = (iNow-(iStartTime+iBucketMs*iFill)); | ||
| 75 | if( iSkip < 0 ) | ||
| 76 | return; | ||
| 77 | iSkip = (iSkip/iBucketMs) + ((iSkip%iBucketMs)?(1):(0)); | ||
| 78 | |||
| 79 | for( int64_t j = 0; j < iSkip; j++ ) | ||
| 80 | { | ||
| 81 | iCurrent = (iCurrent+1)%iCapacity; | ||
| 82 | if( iFill < iCapacity ) | ||
| 83 | { | ||
| 84 | iFill++; | ||
| 85 | } | ||
| 86 | else | ||
| 87 | { | ||
| 88 | iTotal -= aiBucket[iStart]; | ||
| 89 | aiBucket[iStart] = 0; | ||
| 90 | iStart = (iStart+1)%iCapacity; | ||
| 91 | iStartTime += iBucketMs; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | double Bu::Speedometer::getSpeed() | ||
| 98 | { | ||
| 99 | Bu::MutexLocker l( mLock ); | ||
| 100 | _updateBuckets( getCurrentTime() ); | ||
| 101 | |||
| 102 | if( iStartTime < 0 ) | ||
| 103 | return 0.0; | ||
| 104 | |||
| 105 | return (double)iTotal / (double)(iFill*iBucketMs); | ||
| 106 | } | ||
| 107 | |||
| 108 | int32_t Bu::Speedometer::getTotalEvents() | ||
| 109 | { | ||
| 110 | Bu::MutexLocker l( mLock ); | ||
| 111 | return iTotal; | ||
| 112 | } | ||
| 113 | |||
| 114 | int64_t Bu::Speedometer::getCurrentTime() const | ||
| 115 | { | ||
| 116 | struct timeval tv; | ||
| 117 | gettimeofday( &tv, NULL ); | ||
| 118 | return tv.tv_sec*1000 + tv.tv_usec/1000; | ||
| 119 | } | ||
| 120 | |||
diff --git a/src/unstable/speedometer.h b/src/unstable/speedometer.h new file mode 100644 index 0000000..84d21ed --- /dev/null +++ b/src/unstable/speedometer.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | #ifndef BU_SPEEDOMETER_H | ||
| 2 | #define BU_SPEEDOMETER_H | ||
| 3 | |||
| 4 | #include "bu/mutex.h" | ||
| 5 | |||
| 6 | #include <stdint.h> | ||
| 7 | |||
| 8 | namespace Bu | ||
| 9 | { | ||
| 10 | class Speedometer | ||
| 11 | { | ||
| 12 | public: | ||
| 13 | Speedometer( int64_t iBucketMs, int32_t iBucketCount ); | ||
| 14 | virtual ~Speedometer(); | ||
| 15 | |||
| 16 | void addEvent(); | ||
| 17 | double getSpeed(); | ||
| 18 | int32_t getTotalEvents(); | ||
| 19 | void debug(); | ||
| 20 | |||
| 21 | private: | ||
| 22 | void _updateBuckets( int64_t iNow ); | ||
| 23 | /** | ||
| 24 | * Gets the current time in milliseconds. | ||
| 25 | */ | ||
| 26 | int64_t getCurrentTime() const; | ||
| 27 | |||
| 28 | private: | ||
| 29 | uint32_t *aiBucket; | ||
| 30 | uint32_t iTotal; | ||
| 31 | int32_t iCapacity; | ||
| 32 | int32_t iFill; | ||
| 33 | int32_t iStart; | ||
| 34 | int32_t iCurrent; | ||
| 35 | int64_t iBucketMs; | ||
| 36 | int64_t iStartTime; | ||
| 37 | int64_t iWindowSizeMs; | ||
| 38 | int64_t iLastUpdate; | ||
| 39 | mutable Bu::Mutex mLock; | ||
| 40 | }; | ||
| 41 | } | ||
| 42 | |||
| 43 | #endif | ||
