From 0da449e683ebc0745595b172229b8cb3403ff17a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Buga?= <bugadani@gmail.com>
Date: Sat, 22 Jul 2023 14:14:03 +0200
Subject: [PATCH] [broken] add directory hash to metadata objects

---
 src/lib.rs        |  8 +++++++-
 src/ll/objects.rs | 18 ++++++++++++++----
 src/writer.rs     |  5 +++++
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 462f476..359637e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -475,7 +475,7 @@ where
             }
 
             let meta_size =
-                ObjectHeader::byte_count::<M>() + 4 + (blocks + 1) * M::object_location_bytes();
+                ObjectHeader::byte_count::<M>() + 8 + (blocks + 1) * M::object_location_bytes();
 
             match self
                 .blocks
@@ -770,6 +770,12 @@ impl ObjectMover for DataObject {
                 &old_object_reader.path_hash.to_le_bytes(),
             )
             .await?;
+        meta_writer
+            .write(
+                &mut storage.medium,
+                &old_object_reader.directory_hash.to_le_bytes(),
+            )
+            .await?;
 
         let filename_location = if old_object_reader.filename_location == object.location() {
             destination
diff --git a/src/ll/objects.rs b/src/ll/objects.rs
index b564db8..a7293af 100644
--- a/src/ll/objects.rs
+++ b/src/ll/objects.rs
@@ -433,9 +433,9 @@ impl ObjectHeader {
 pub struct MetadataObjectHeader<M: StorageMedium> {
     pub object: ObjectHeader,
     pub path_hash: u32,
+    pub directory_hash: u32,
     pub filename_location: ObjectLocation,
     data_object_cursor: usize, // Used to iterate through the list of object locations.
-    _parent: Option<ObjectLocation>,
     _medium: PhantomData<M>,
 }
 
@@ -446,7 +446,7 @@ impl<M: StorageMedium> MetadataObjectHeader<M> {
     ) -> Result<Option<ObjectLocation>, StorageError> {
         log::trace!("MetadataObjectHeader::next_object_location()");
 
-        let data_offset = 4 + M::object_location_bytes(); // path hash + filename location
+        let data_offset = 4 + 4 + M::object_location_bytes(); // path hash + folder hash + filename location
         if self.data_object_cursor
             >= self
                 .object
@@ -776,13 +776,23 @@ impl<M: StorageMedium> ObjectInfo<M> {
             )
             .await?;
 
+        let mut directory_hash_bytes = [0; 4];
+        let directory_hash_offset = path_hash_offset + 4;
+        medium
+            .read(
+                self.location().block,
+                directory_hash_offset,
+                &mut directory_hash_bytes,
+            )
+            .await?;
+
         let mut filename_location_bytes = [0; 8];
         let filename_location_bytes = &mut filename_location_bytes[0..M::object_location_bytes()];
 
         medium
             .read(
                 self.location().block,
-                path_hash_offset + 4,
+                directory_hash_offset + 4,
                 filename_location_bytes,
             )
             .await?;
@@ -790,9 +800,9 @@ impl<M: StorageMedium> ObjectInfo<M> {
         Ok(MetadataObjectHeader {
             object: self.header,
             path_hash: u32::from_le_bytes(path_hash_bytes),
+            directory_hash: u32::from_le_bytes(directory_hash_bytes),
             filename_location: ObjectLocation::from_bytes::<M>(filename_location_bytes),
             data_object_cursor: 0,
-            _parent: None,
             _medium: PhantomData,
         })
     }
diff --git a/src/writer.rs b/src/writer.rs
index fe963d6..a27e4d6 100644
--- a/src/writer.rs
+++ b/src/writer.rs
@@ -164,12 +164,14 @@ where
     ) -> Result<(), StorageError> {
         log::debug!("Writer::create(path = {:?})", path);
 
+        // TODO: lift this? we need to look up the directory
         if path.contains(&['/', '\\'][..]) {
             log::warn!("Path contains invalid characters");
             return Err(StorageError::InvalidOperation);
         }
 
         let path_hash = hash_path(path);
+        let directory_hash = hash_path(""); // TODO
         let est_page_count = 1 + storage.estimate_data_chunks(op.estimate_length())?;
 
         // this is mutable because we can fail mid-writing. 4 bytes to store the path hash
@@ -199,6 +201,9 @@ where
         meta_writer
             .write(&mut storage.medium, &path_hash.to_le_bytes())
             .await?;
+        meta_writer
+            .write(&mut storage.medium, &directory_hash.to_le_bytes())
+            .await?;
 
         storage
             .write_location(&mut meta_writer, filename_location)