progress.h 1.3 KB

1234567891011121314151617181920212223242526272829303132
  1. // Stage estimates never announce the next operation before the worker reaches it.
  2. #pragma once
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <cstdint>
  6. struct InstallProgress {
  7. int stage = 0;
  8. double value = 0;
  9. std::uint64_t stageStarted;
  10. std::uint64_t updated;
  11. explicit InstallProgress(std::uint64_t now) : stageStarted(now), updated(now) {}
  12. void Advance(int nextStage, std::uint64_t now) {
  13. if (nextStage > stage && nextStage <= 4) {
  14. stage = nextStage;
  15. stageStarted = now;
  16. }
  17. const double boundaries[] = {0, 2, 22, 92, 94, 100};
  18. const double seconds[] = {3, 33, 120, 1, 11};
  19. const double elapsed = (now - stageStarted) / 1000.0;
  20. // File copy and cleanup expose no byte callbacks. Approach the stage limit
  21. // gradually, leaving completion to the worker rather than a timer.
  22. const double ratio = elapsed / seconds[stage];
  23. const double fraction = ratio <= 0.95 ? ratio : 1 - 0.05 * std::exp(-(ratio - 0.95));
  24. const double target = boundaries[stage] + (boundaries[stage + 1] - boundaries[stage]) * fraction;
  25. const double bounded = std::min(boundaries[stage + 1] - 0.1, target);
  26. value = std::min(std::max(value, bounded), value + (now - updated) / 1000.0 * 10);
  27. updated = now;
  28. }
  29. };