-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdisk_space_estimator.cpp
64 lines (51 loc) · 1.67 KB
/
disk_space_estimator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "disk_space_estimator.h"
#include <stdio.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <memory>
#include "metrics.h"
#include "timebase.h"
DiskSpaceEstimator::DiskSpaceEstimator(DiskSpaceEstimator::callback_t callback)
: callback(callback)
{
global_metrics.add("disk_free_bytes", &metric_disk_free_bytes, Metrics::TYPE_GAUGE);
}
void DiskSpaceEstimator::report_write(const std::string &filename, uint64_t pts)
{
if (filename != last_filename) {
last_filename = filename;
measure_points.clear();
}
// Reject points that are out-of-order (happens with B-frames).
if (!measure_points.empty() && pts < measure_points.back().pts) {
return;
}
// Remove too old points.
while (measure_points.size() > 1 && measure_points.front().pts + window_length < pts) {
measure_points.pop_front();
}
struct stat st;
if (stat(filename.c_str(), &st) == -1) {
perror(filename.c_str());
return;
}
struct statfs fst;
if (statfs(filename.c_str(), &fst) == -1) {
perror(filename.c_str());
return;
}
off_t free_bytes = off_t(fst.f_bavail) * fst.f_frsize;
metric_disk_free_bytes = free_bytes;
if (!measure_points.empty()) {
double bytes_per_second = double(st.st_size - measure_points.front().size) /
(pts - measure_points.front().pts) * TIMEBASE;
double seconds_left = free_bytes / bytes_per_second;
// Only report every second, since updating the UI can be expensive.
if (last_pts_reported == 0 || pts - last_pts_reported >= TIMEBASE) {
callback(free_bytes, seconds_left);
last_pts_reported = pts;
}
}
measure_points.push_back({ pts, st.st_size });
}
DiskSpaceEstimator *global_disk_space_estimator = nullptr; // Created in MainWindow::MainWindow().