Skip to content

Commit

Permalink
parallel travesal algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
solidiquis committed Nov 7, 2023
1 parent 4291baa commit 3c68b84
Show file tree
Hide file tree
Showing 10 changed files with 371 additions and 74 deletions.
54 changes: 44 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ name = "erd"
path = "src/main.rs"

[dependencies]
ahash = "0.8.6"
ansi_term = "0.12.1"
anyhow = "1.0.75"
chrono = { version = "0.4.24", default-features = false, features = ["clock", "std"] }
Expand Down
50 changes: 34 additions & 16 deletions src/disk/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::{error::prelude::*, user::enums::BytePresentation};
use crate::user::enums::BytePresentation;
use ignore::DirEntry;
use std::{
fmt::{self, Display},
fs::Metadata,
fs::{self, Metadata},
io,
ops::AddAssign,
};

Expand Down Expand Up @@ -92,35 +93,52 @@ impl Usage {
/// Gets the word count. Words are delimited by a whitespace or a sequence of whitespaces.
/// Directories are initialized to 0. The `follow` argument determines whether or not to query the
/// symlink target, otherwise the symlink will have a word count of 0.
pub fn init_word_count(data: &DirEntry, metadata: &Metadata, follow: bool) -> Result<Self> {
pub fn init_word_count(
data: &DirEntry,
metadata: &Metadata,
follow: bool,
) -> Result<Self, io::Error> {
if metadata.is_dir() || (metadata.is_symlink() && !follow) {
return Ok(Self::WordCount(0));
}

let word_count = std::fs::read_to_string(data.path())
.into_report(ErrorCategory::Internal)
.map(|data| data.split_whitespace().count())?;
let word_count =
std::fs::read_to_string(data.path()).map(|data| data.split_whitespace().count())?;

u64::try_from(word_count)
.into_report(ErrorCategory::Internal)
.map(Self::WordCount)
let word_count = u64::try_from(word_count).map_or_else(
|e| {
log::warn!("Usage::init_word_count {e}");
Self::WordCount(word_count as u64)
},
Self::WordCount,
);

Ok(word_count)
}

/// Gets the line count. Lines are delimited by the new-line ASCII char. Directories are
/// initialized to 0. The `follow` argument determines whether or not to query the symlink
/// target, otherwise the symlink will have a count of 0.
pub fn init_line_count(data: &DirEntry, metadata: &Metadata, follow: bool) -> Result<Self> {
pub fn init_line_count(
data: &DirEntry,
metadata: &Metadata,
follow: bool,
) -> Result<Self, io::Error> {
if metadata.is_dir() || (metadata.is_symlink() && !follow) {
return Ok(Self::LineCount(0));
}

let line_count = std::fs::read_to_string(data.path())
.into_report(ErrorCategory::Internal)
.map(|data| data.lines().count())?;
let line_count = fs::read_to_string(data.path()).map(|data| data.lines().count())?;

let line_count = u64::try_from(line_count).map_or_else(
|e| {
log::warn!("Usage::init_line_count {e}");
Self::WordCount(line_count as u64)
},
Self::LineCount,
);

u64::try_from(line_count)
.into_report(ErrorCategory::Internal)
.map(Self::WordCount)
Ok(line_count)
}

/// Gets the underlying numeric value representing the disk usage
Expand Down
2 changes: 1 addition & 1 deletion src/file/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl Inode {
}

#[derive(Debug, thiserror::Error)]
#[error("Insufficient information to compute inode")]
#[error("Insufficient information to compute inode.")]
pub struct INodeError;

impl TryFrom<&Metadata> for Inode {
Expand Down
14 changes: 7 additions & 7 deletions src/file/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use crate::{
disk,
error::prelude::*,
user::{enums::Metric, Context},
};
use ignore::DirEntry;
use std::{
fs::{self, Metadata},
io,
ops::Deref,
};

/// Concerned with querying information about a file's underlying inode.
pub mod inode;
use inode::Inode;
use inode::{INodeError, Inode};

/// Erdtree's wrapper around [`DirEntry`], it's metadata ([`Metadata`]). Also contains disk usage
/// information of files. Directories will always be initialized to have a size of zero as they
Expand Down Expand Up @@ -42,13 +42,13 @@ impl File {
follow,
..
}: &Context,
) -> Result<Self> {
) -> Result<Self, io::Error> {
let path = data.path();

let metadata = if *follow {
fs::metadata(path).into_report(ErrorCategory::System)?
fs::metadata(path)?
} else {
fs::symlink_metadata(path).into_report(ErrorCategory::System)?
fs::symlink_metadata(path)?
};

let size = match metric {
Expand All @@ -65,8 +65,8 @@ impl File {
}

/// Attempts to query the [`File`]'s underlying inode which is represented by [`Inode`].
pub fn inode(&self) -> Result<Inode> {
Inode::try_from(&self.metadata).into_report(ErrorCategory::Internal)
pub fn inode(&self) -> Result<Inode, INodeError> {
Inode::try_from(&self.metadata)
}

/// Gets a mutable reference to the `size` field.
Expand Down
10 changes: 2 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,12 @@ fn run() -> error::Result<()> {
.transpose()?;

let file_tree = if ctx.threads > 1 {

Check warning on line 46 in src/main.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused variable: `file_tree`

Check warning on line 46 in src/main.rs

View workflow job for this annotation

GitHub Actions / Check

unused variable: `file_tree`

Check warning on line 46 in src/main.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused variable: `file_tree`

Check warning on line 46 in src/main.rs

View workflow job for this annotation

GitHub Actions / Check

unused variable: `file_tree`
FileTree::init(&ctx)?
FileTree::init_parallel(&ctx)?
} else {
FileTree::init(&ctx)?
};

let Some(indextree::NodeEdge::Start(id)) = file_tree.traverse().next() else {
panic!("womp");
};

let root = file_tree[id].get();

println!("{root:?}");
//println!("{}", file_tree[file_tree.root_id()].get().size().value());

if let Some(logger) = logger {
logger.flush();
Expand Down
Loading

0 comments on commit 3c68b84

Please sign in to comment.