datafusion_common/display/
human_readable.rs1pub mod units {
22 pub const TB: u64 = 1 << 40;
23 pub const GB: u64 = 1 << 30;
24 pub const MB: u64 = 1 << 20;
25 pub const KB: u64 = 1 << 10;
26}
27
28pub fn human_readable_size(size: usize) -> String {
30 use units::*;
31
32 let size = size as u64;
33 let (value, unit) = {
34 if size >= 2 * TB {
35 (size as f64 / TB as f64, "TB")
36 } else if size >= 2 * GB {
37 (size as f64 / GB as f64, "GB")
38 } else if size >= 2 * MB {
39 (size as f64 / MB as f64, "MB")
40 } else if size >= 2 * KB {
41 (size as f64 / KB as f64, "KB")
42 } else {
43 (size as f64, "B")
44 }
45 };
46 format!("{value:.1} {unit}")
47}
48
49pub fn human_readable_count(count: usize) -> String {
51 let count = count as u64;
52 let (value, unit) = {
53 if count >= 1_000_000_000_000 {
54 (count as f64 / 1_000_000_000_000.0, " T")
55 } else if count >= 1_000_000_000 {
56 (count as f64 / 1_000_000_000.0, " B")
57 } else if count >= 1_000_000 {
58 (count as f64 / 1_000_000.0, " M")
59 } else if count >= 1_000 {
60 (count as f64 / 1_000.0, " K")
61 } else {
62 return count.to_string();
63 }
64 };
65
66 if value >= 100.0 {
70 format!("{value:.1}{unit}")
71 } else {
72 format!("{value:.2}{unit}")
73 }
74}
75
76pub fn human_readable_duration(nanos: u64) -> String {
78 const NANOS_PER_SEC: f64 = 1_000_000_000.0;
79 const NANOS_PER_MILLI: f64 = 1_000_000.0;
80 const NANOS_PER_MICRO: f64 = 1_000.0;
81
82 let nanos_f64 = nanos as f64;
83
84 if nanos >= 1_000_000_000 {
85 format!("{:.2}s", nanos_f64 / NANOS_PER_SEC)
87 } else if nanos >= 1_000_000 {
88 format!("{:.2}ms", nanos_f64 / NANOS_PER_MILLI)
90 } else if nanos >= 1_000 {
91 format!("{:.2}µs", nanos_f64 / NANOS_PER_MICRO)
93 } else {
94 format!("{nanos}ns")
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn test_human_readable_count() {
105 assert_eq!(human_readable_count(0), "0");
106 assert_eq!(human_readable_count(1), "1");
107 assert_eq!(human_readable_count(999), "999");
108 assert_eq!(human_readable_count(1_000), "1.00 K");
109 assert_eq!(human_readable_count(10_100), "10.10 K");
110 assert_eq!(human_readable_count(1_532), "1.53 K");
111 assert_eq!(human_readable_count(99_999), "100.00 K");
112 assert_eq!(human_readable_count(1_000_000), "1.00 M");
113 assert_eq!(human_readable_count(1_532_000), "1.53 M");
114 assert_eq!(human_readable_count(99_000_000), "99.00 M");
115 assert_eq!(human_readable_count(123_456_789), "123.5 M");
116 assert_eq!(human_readable_count(1_000_000_000), "1.00 B");
117 assert_eq!(human_readable_count(1_532_000_000), "1.53 B");
118 assert_eq!(human_readable_count(999_999_999_999), "1000.0 B");
119 assert_eq!(human_readable_count(1_000_000_000_000), "1.00 T");
120 assert_eq!(human_readable_count(42_000_000_000_000), "42.00 T");
121 }
122
123 #[test]
124 fn test_human_readable_duration() {
125 assert_eq!(human_readable_duration(0), "0ns");
126 assert_eq!(human_readable_duration(1), "1ns");
127 assert_eq!(human_readable_duration(999), "999ns");
128 assert_eq!(human_readable_duration(1_000), "1.00µs");
129 assert_eq!(human_readable_duration(1_234), "1.23µs");
130 assert_eq!(human_readable_duration(999_999), "1000.00µs");
131 assert_eq!(human_readable_duration(1_000_000), "1.00ms");
132 assert_eq!(human_readable_duration(11_295_377), "11.30ms");
133 assert_eq!(human_readable_duration(1_234_567), "1.23ms");
134 assert_eq!(human_readable_duration(999_999_999), "1000.00ms");
135 assert_eq!(human_readable_duration(1_000_000_000), "1.00s");
136 assert_eq!(human_readable_duration(1_234_567_890), "1.23s");
137 assert_eq!(human_readable_duration(42_000_000_000), "42.00s");
138 }
139}