diff --git a/src/queue/mod.rs b/src/queue/mod.rs index 33df534..31ee447 100644 --- a/src/queue/mod.rs +++ b/src/queue/mod.rs @@ -3,6 +3,7 @@ mod iter; mod receiver; mod sender; +mod size; pub use iter::QueueIter; pub use receiver::{Receiver, ReceiverBuilder, RecvGuard}; diff --git a/src/queue/receiver.rs b/src/queue/receiver.rs index 073c305..45ccd3f 100644 --- a/src/queue/receiver.rs +++ b/src/queue/receiver.rs @@ -191,6 +191,16 @@ impl Receiver { ReceiverBuilder::default().open(base) } + /// Gets the total size of the queue in bytes in disk. + /// + /// # Errors + /// + /// This function will return an IO error if any errors are encountered while going + /// throught the listed files in disk. + pub fn get_size(&self) -> io::Result { + super::size::total_directory_size(&self.base) + } + /// Starts a transaction in the queue. fn begin(&mut self) { log::debug!("begin transaction in {:?} at {:?}", self.base, self.state); diff --git a/src/queue/sender.rs b/src/queue/sender.rs index 6748a0e..3b9af49 100644 --- a/src/queue/sender.rs +++ b/src/queue/sender.rs @@ -202,6 +202,16 @@ impl Sender { SenderBuilder::default().open(base) } + /// Gets the total size of the queue in bytes in disk. + /// + /// # Errors + /// + /// This function will return an IO error if any errors are encountered while going + /// throught the listed files in disk. + pub fn get_size(&self) -> io::Result { + super::size::total_directory_size(&self.base) + } + /// Saves the sender queue state. You do not need to use method in most /// circumstances, since it is automatically done on drop (yes, it will be /// called eve if your thread panics). However, you can use this function to diff --git a/src/queue/size.rs b/src/queue/size.rs new file mode 100644 index 0000000..aa0b8bd --- /dev/null +++ b/src/queue/size.rs @@ -0,0 +1,25 @@ +//! Utilities for calculating the size of a queue. + +use std::path::Path; +use std::{fs, io}; + +/// Goes through each file in the given directory _non-recursively_ and adds up all their +/// sizes. +pub(crate) fn total_directory_size(dir: &Path) -> Result { + let mut size = 0; + + for maybe_entry in fs::read_dir(dir)? { + let metadata = maybe_entry?.metadata()?; + if !metadata.is_file() { + continue; + } + + // Here, we will count the size of _all_ files, not only of the queue segment + // files `*.q`. This might be useful for wusers with many small queues. So, no + // filtering based on extension. + + size += metadata.len(); + } + + Ok(size) +} diff --git a/src/state.rs b/src/state.rs index 37da9f6..6d00238 100644 --- a/src/state.rs +++ b/src/state.rs @@ -134,6 +134,8 @@ impl QueueStatePersistence { QueueStatePersistence::default() } + /// Opens a new file persistence stored inside the _folder_ `base` (i.e., it will + /// look for the file `{base}/recv-metadata`). pub fn open>(&mut self, base: P) -> io::Result { let path = recv_persistence_filename(base); self.path = Some(path.clone());