[pbs-devel] [RFC proxmox-backup v2 3/4] HumanByte: use u64 instead of f64 to store size

Dietmar Maurer dietmar at proxmox.com
Wed Nov 17 14:37:19 CET 2021


Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
 pbs-api-types/src/human_byte.rs | 84 ++++++++++++++++-----------------
 1 file changed, 42 insertions(+), 42 deletions(-)

diff --git a/pbs-api-types/src/human_byte.rs b/pbs-api-types/src/human_byte.rs
index df90d446..4d8c4f21 100644
--- a/pbs-api-types/src/human_byte.rs
+++ b/pbs-api-types/src/human_byte.rs
@@ -26,22 +26,22 @@ pub enum SizeUnit {
 }
 
 impl SizeUnit {
-    pub fn factor(&self) -> f64 {
+    pub fn factor(&self) -> u64 {
         match self {
-            SizeUnit::None => 1.0,
-            SizeUnit::Byte => 1.0,
-
-            SizeUnit::Kilo | SizeUnit::KByte  => 1_000.0,
-            SizeUnit::Mega | SizeUnit::MByte => 1_000_000.0,
-            SizeUnit::Giga | SizeUnit::GByte => 1_000_000_000.0,
-            SizeUnit::Tera | SizeUnit::TByte => 1_000_000_000_000.0,
-            SizeUnit::Peta | SizeUnit::PByte => 1_000_000_000_000_000.0,
-
-            SizeUnit::Kibi => 1024.0,
-            SizeUnit::Mebi => 1024.0*1024.0,
-            SizeUnit::Gibi => 1024.0*1024.0*1024.0,
-            SizeUnit::Tebi => 1024.0*1024.0*1024.0*1024.0,
-            SizeUnit::Pebi => 1024.0*1024.0*1024.0*1024.0*1024.0,
+            SizeUnit::None => 1,
+            SizeUnit::Byte => 1,
+
+            SizeUnit::Kilo | SizeUnit::KByte  => 1_000,
+            SizeUnit::Mega | SizeUnit::MByte => 1_000_000,
+            SizeUnit::Giga | SizeUnit::GByte => 1_000_000_000,
+            SizeUnit::Tera | SizeUnit::TByte => 1_000_000_000_000,
+            SizeUnit::Peta | SizeUnit::PByte => 1_000_000_000_000_000,
+
+            SizeUnit::Kibi => 1024,
+            SizeUnit::Mebi => 1024*1024,
+            SizeUnit::Gibi => 1024*1024*1024,
+            SizeUnit::Tebi => 1024*1024*1024*1024,
+            SizeUnit::Pebi => 1024*1024*1024*1024*1024,
         }
     }
 
@@ -122,7 +122,7 @@ fn strip_unit(v: &str) -> (&str, SizeUnit) {
 #[derive(Debug, Copy, Clone, UpdaterType)]
 /// Byte size with unit
 pub struct HumanByte {
-    size: f64,
+    size: u64,
     unit: SizeUnit,
 }
 
@@ -144,12 +144,12 @@ impl ApiType for HumanByte {
 impl HumanByte {
 
     pub fn new_decimal(size: u64) -> Self {
-        let this = HumanByte { size: size as f64, unit: SizeUnit::None };
+        let this = HumanByte { size: size, unit: SizeUnit::None };
         this.auto_unit_decimal()
     }
 
     pub fn new_binary(size: u64) -> Self {
-        let this = HumanByte { size: size as f64, unit: SizeUnit::None };
+        let this = HumanByte { size: size, unit: SizeUnit::None };
         this.auto_unit_binary()
     }
 
@@ -178,15 +178,15 @@ impl HumanByte {
     }
 
     pub fn auto_unit_decimal(mut self) -> Self {
-        self.unit = if self.size >= 1_000_000_000_000_000.0 {
+        self.unit = if self.size >= 1_000_000_000_000_000 {
             SizeUnit::PByte
-        } else if self.size >= 1_000_000_000_000.0 {
+        } else if self.size >= 1_000_000_000_000 {
             SizeUnit::TByte
-        } else if self.size >= 1_000_000_000.0 {
+        } else if self.size >= 1_000_000_000 {
             SizeUnit::GByte
-        } else if self.size >= 1_000_000.0 {
+        } else if self.size >= 1_000_000 {
             SizeUnit::MByte
-        } else if self.size >= 1_000.0 {
+        } else if self.size >= 1_000 {
             SizeUnit::KByte
         } else {
             SizeUnit::None
@@ -201,7 +201,7 @@ impl std::fmt::Display for HumanByte {
 
         let unit = self.unit;
 
-        let size = size/unit.factor();
+        let size = (size as f64)/(unit.factor() as f64);
         let unit_str = unit.unit_str();
 
         if unit == SizeUnit::Byte || unit == SizeUnit::None {
@@ -237,9 +237,9 @@ impl FromStr for HumanByte {
             bail!("size may not be negative");
         }
 
-        let size = size*unit.factor();
+        let size = (size*(unit.factor() as f64)) as u64;
 
-        Ok(Self { size: size, unit })
+        Ok(Self { size, unit })
     }
 
 }
@@ -252,7 +252,7 @@ fn test_human_byte_parser() -> Result<(), Error> {
 
     assert!("-10".parse::<HumanByte>().is_err()); // negative size
 
-    fn test(v: &str, size: f64, unit: SizeUnit, as_str: &str) -> Result<(), Error> {
+    fn test(v: &str, size: u64, unit: SizeUnit, as_str: &str) -> Result<(), Error> {
         let h: HumanByte = v.parse()?;
 
         if h.size != size {
@@ -271,29 +271,29 @@ fn test_human_byte_parser() -> Result<(), Error> {
         Ok(())
     }
 
-    test("14.4", 14.4, SizeUnit::None, "14")?;
+    test("14.4", 14, SizeUnit::None, "14")?;
 
-    test("14", 14.0, SizeUnit::None, "14")?;
-    test("987654321", 987654321.0, SizeUnit::None, "987654321")?;
+    test("14", 14, SizeUnit::None, "14")?;
+    test("987654321", 987654321, SizeUnit::None, "987654321")?;
 
-    test("1300b", 1300.0, SizeUnit::Byte, "1300 B")?;
-    test("1300B", 1300.0, SizeUnit::Byte, "1300 B")?;
+    test("1300b", 1300, SizeUnit::Byte, "1300 B")?;
+    test("1300B", 1300, SizeUnit::Byte, "1300 B")?;
 
-    test("1.5KB", 1500.0, SizeUnit::KByte, "1.5 KB")?;
-    test("1.5kb", 1500.0, SizeUnit::KByte, "1.5 KB")?;
-    test("1.654321MB", 1_654_321.0, SizeUnit::MByte, "1.654 MB")?;
+    test("1.5KB", 1500, SizeUnit::KByte, "1.5 KB")?;
+    test("1.5kb", 1500, SizeUnit::KByte, "1.5 KB")?;
+    test("1.654321MB", 1_654_321, SizeUnit::MByte, "1.654 MB")?;
 
-    test("2.0GB", 2_000_000_000.0, SizeUnit::GByte, "2 GB")?;
+    test("2.0GB", 2_000_000_000, SizeUnit::GByte, "2 GB")?;
 
-    test("1.4TB", 1_400_000_000_000.0, SizeUnit::TByte, "1.4 TB")?;
-    test("1.4tb", 1_400_000_000_000.0, SizeUnit::TByte, "1.4 TB")?;
+    test("1.4TB", 1_400_000_000_000, SizeUnit::TByte, "1.4 TB")?;
+    test("1.4tb", 1_400_000_000_000, SizeUnit::TByte, "1.4 TB")?;
 
-    test("2KiB", 2048.0, SizeUnit::Kibi, "2 KiB")?;
-    test("2kib", 2048.0, SizeUnit::Kibi, "2 KiB")?;
+    test("2KiB", 2048, SizeUnit::Kibi, "2 KiB")?;
+    test("2kib", 2048, SizeUnit::Kibi, "2 KiB")?;
 
-    test("2.3456MiB", 2.3456*1024.0*1024.0, SizeUnit::Mebi, "2.345 MiB")?;
+    test("2.3456MiB", (2.3456*1024.0*1024.0) as u64, SizeUnit::Mebi, "2.345 MiB")?;
 
-    test("4gib", 4.0*1024.0*1024.0*1024.0, SizeUnit::Gibi, "4 GiB")?;
+    test("4gib", (4.0*1024.0*1024.0*1024.0) as u64, SizeUnit::Gibi, "4 GiB")?;
 
     Ok(())
 }
-- 
2.30.2






More information about the pbs-devel mailing list