public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Dietmar Maurer <dietmar@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [RFC proxmox-backup v2 3/4] HumanByte: use u64 instead of f64 to store size
Date: Wed, 17 Nov 2021 14:37:19 +0100	[thread overview]
Message-ID: <20211117133720.1799124-4-dietmar@proxmox.com> (raw)
In-Reply-To: <20211117133720.1799124-1-dietmar@proxmox.com>

Signed-off-by: Dietmar Maurer <dietmar@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





  parent reply	other threads:[~2021-11-17 13:37 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-17 13:37 [pbs-devel] [RFC proxmox-backup v2 0/4] more flexible HumanByte type Dietmar Maurer
2021-11-17 13:37 ` [pbs-devel] [RFC proxmox-backup v2 1/4] pbs-api-types: " Dietmar Maurer
2021-11-17 13:37 ` [pbs-devel] [RFC proxmox-backup v2 2/4] use HumanByte for traffic-control config Dietmar Maurer
2021-11-17 13:37 ` Dietmar Maurer [this message]
2021-11-17 13:37 ` [pbs-devel] [RFC proxmox-backup v2 4/4] HumanByte: do not store unit (always compute canonical form) Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211117133720.1799124-4-dietmar@proxmox.com \
    --to=dietmar@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal