From 52929cef24703ace37859c24477140c880958b59 Mon Sep 17 00:00:00 2001
From: AmauryBrodu <60550980+AmauryBrodu@users.noreply.github.com>
Date: Wed, 29 Mar 2023 13:17:21 +0200
Subject: [PATCH] added the bitmap, tests still need to be done

---
 src/utility/bitmap.rs | 102 ++++++++++++++++++++++++++++++++++++++++++
 src/utility/mod.rs    |   3 +-
 2 files changed, 104 insertions(+), 1 deletion(-)
 create mode 100644 src/utility/bitmap.rs

diff --git a/src/utility/bitmap.rs b/src/utility/bitmap.rs
new file mode 100644
index 0000000..a34e5b4
--- /dev/null
+++ b/src/utility/bitmap.rs
@@ -0,0 +1,102 @@
+pub const BITS_IN_BYTE: usize = 8;
+pub const BITS_IN_WORD: usize = 32;
+
+use std::fs::File;
+use std::io::{Cursor, Write, Read};
+
+pub struct BitMap {
+    num_bits: usize,
+    num_words: usize,
+    map: Vec<u32>,
+}
+
+impl BitMap {
+
+    pub fn mark(&mut self, which: usize) {
+        assert!(which >= 0 && which < self.num_bits);
+        self.map[which / BITS_IN_WORD] |= 1 << (which % BITS_IN_WORD);
+    }
+
+    pub fn test(&self, which: usize) -> bool {
+        assert!(which < self.num_bits);
+        (self.map[which / BITS_IN_WORD] & (1 << (which % BITS_IN_WORD))) != 0
+    }
+
+    pub fn find(&mut self) -> i32 {
+        for i in 0..self.num_bits {
+            if !self.test(i) {
+                self.mark(i);
+                return i as i32;
+            }
+        }
+        -1
+    }
+
+    pub fn clear(&mut self, which: usize) {
+        assert!(which < self.num_bits, "index out of range");
+
+        let word_idx = which / BITS_IN_WORD;              
+        let bit_idx = which % BITS_IN_WORD;                 
+        self.map[word_idx] &= !(1 << bit_idx);    
+    }
+
+    pub fn num_clear(&self) -> i32 {
+        let mut count = 0;
+        for i in 0..self.num_bits {
+            if !self.test(i) {
+                count += 1;
+            }
+        }
+        count
+    }
+
+    pub fn print(&self) {
+        println!("Bitmap set:");
+        for i in 0..self.num_bits {
+            if self.test(i) {
+                print!("{}, ", i);
+            }
+        }
+        println!();
+    }
+
+
+
+    pub fn fetch_from(&mut self, file_path: &str) -> std::io::Result<&Vec<u32>> {
+        // Ouvre le fichier en mode lecture seule
+        let mut file = File::open(file_path)?;
+
+        // Lit les octets du fichier dans un buffer
+        let mut buffer = vec![0; self.num_words * std::mem::size_of::<u32>()];
+        file.read_exact(&mut buffer)?;
+
+        // Convertit les octets en vecteur de u32
+        self.map = vec![0; self.num_words];
+        for i in 0..self.num_words {
+            let j = i * std::mem::size_of::<u32>();
+            let bytes = [
+                buffer[j], buffer[j+1], buffer[j+2], buffer[j+3]
+            ];
+            self.map[i] = u32::from_le_bytes(bytes);
+        }
+
+        Ok(&self.map)
+    }
+
+    pub fn write_back(&mut self, file_path: &str) -> std::io::Result<()> {
+        // Encapsule le vecteur dans un std::io::Cursor pour l'utiliser comme un std::io::Write
+        let mut cursor = Cursor::new(Vec::<u8>::new());
+        for u32_val in self.map.as_mut_slice() {
+            cursor.write_all(&u32_val.to_le_bytes())?;
+        }
+
+        // Ouvre le fichier en mode écriture
+        let mut file = File::create(file_path)?;
+
+        // Écrit les données dans le fichier
+        file.write_all(&cursor.into_inner())?;
+
+        Ok(())
+    }
+
+}
\ No newline at end of file
diff --git a/src/utility/mod.rs b/src/utility/mod.rs
index 651aed7..6db23f2 100644
--- a/src/utility/mod.rs
+++ b/src/utility/mod.rs
@@ -1 +1,2 @@
-pub mod list;
\ No newline at end of file
+pub mod list;
+pub mod bitmap;
\ No newline at end of file