percentile.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #pragma once
  2. #include "percentile_base.h"
  3. namespace NMonitoring {
  4. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5. // Percentile tracker for monitoring
  6. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7. template <size_t BUCKET_SIZE, size_t BUCKET_COUNT, size_t FRAME_COUNT>
  8. struct TPercentileTracker : public TPercentileBase {
  9. TAtomic Items[BUCKET_COUNT];
  10. TAtomicBase Frame[FRAME_COUNT][BUCKET_COUNT];
  11. size_t CurrentFrame;
  12. TPercentileTracker()
  13. : CurrentFrame(0)
  14. {
  15. for (size_t i = 0; i < BUCKET_COUNT; ++i) {
  16. AtomicSet(Items[i], 0);
  17. }
  18. for (size_t frame = 0; frame < FRAME_COUNT; ++frame) {
  19. for (size_t bucket = 0; bucket < BUCKET_COUNT; ++bucket) {
  20. Frame[frame][bucket] = 0;
  21. }
  22. }
  23. }
  24. void Increment(size_t value) {
  25. AtomicIncrement(Items[Min((value + BUCKET_SIZE - 1) / BUCKET_SIZE, BUCKET_COUNT - 1)]);
  26. }
  27. // shift frame (call periodically)
  28. void Update() {
  29. TVector<TAtomicBase> totals(BUCKET_COUNT);
  30. totals.resize(BUCKET_COUNT);
  31. TAtomicBase total = 0;
  32. for (size_t i = 0; i < BUCKET_COUNT; ++i) {
  33. TAtomicBase item = AtomicGet(Items[i]);
  34. TAtomicBase prevItem = Frame[CurrentFrame][i];
  35. Frame[CurrentFrame][i] = item;
  36. total += item - prevItem;
  37. totals[i] = total;
  38. }
  39. for (size_t i = 0; i < Percentiles.size(); ++i) {
  40. TPercentile &percentile = Percentiles[i];
  41. auto threshold = (TAtomicBase)(percentile.first * (float)total);
  42. threshold = Min(threshold, total);
  43. auto it = LowerBound(totals.begin(), totals.end(), threshold);
  44. size_t index = it - totals.begin();
  45. (*percentile.second) = index * BUCKET_SIZE;
  46. }
  47. CurrentFrame = (CurrentFrame + 1) % FRAME_COUNT;
  48. }
  49. };
  50. } // NMonitoring