Compare commits

..

3 Commits

Author SHA1 Message Date
Avril ec8ee9db3c
Merge branch 'master' into directory-aware-recursion-flag
4 weeks ago
Avril 97cbd04bf5
Started `-R` replacement.
4 weeks ago
Avril 80bd82fedc
Added info in TODO.md
2 years ago

@ -0,0 +1,4 @@
# TODO: Support -R - Non-blind recursion (like sxiv-ordered)
## Requires
A mpsc channel refactor to support sending parents...

@ -46,6 +46,20 @@ async fn work_on(cfg: work::Config, mut into: mpsc::Receiver<work::FileInfo>) ->
Ok(map)
}
async fn work_on_tree(cfg: work::Config, mut into: mpsc::Receiver<(Option<work::FileInfo>, work::FileInfo)>) -> eyre::Result<work::NestedFsTreeMap>
{
//TODO: How to refactor the mpsc channel to support this and the blind (above) version???
use work::*;
let mut map = NestedFsTreeMap::new(cfg);
while let Some((parent, file)) = into.recv().await {
if cfg!(debug_assertions) {
trace!("insert {:?}/ +{}", parent, map.len());
}
map.insert(parent, file);
}
Ok(map)
}
async fn walk_paths<I, P>(paths: I, cfg: walk::Config, worker_cfg: &std::sync::Arc<work::Config>, to: mpsc::Sender<work::FileInfo>) -> eyre::Result<usize>
where I: futures::stream::Stream<Item = P>,
P: AsRef<std::path::Path>

@ -33,6 +33,7 @@ pub struct FileInfo
state: Arc<Config>, //TODO: XXX: This will be a *severe* slowdown... How can we have just a reference here? Thread local? `tokio::task_local!`? Global static?
path: PathBuf,
meta: Metadata,
dir: bool,
}
impl FileInfo
@ -53,6 +54,7 @@ impl FileInfo
{
Self {
state: config.into(),
dir: meta.is_dir(),
path, meta
}
}
@ -122,6 +124,46 @@ impl order::Orderer<FileInfo> for FileInfo
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct FSTimeMap(Arc<Config>, BTreeSet<order::Ordered<FileInfo, FileInfo>>);
/// Maps files based on their time maintaining directory structure.
///
/// # Note
/// The output of this ordering is still a flat-map. Children are corrently grouped beneath their parents.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct NestedFsTreeMap(Arc<Config>, BTreeSet<order::Ordered<NestedFileInfo, FileInfo>>);
impl NestedFsTreeMap
{
#[inline]
pub fn new(config: impl Into<Config>) -> Self
{
Self (Arc::new(config.into()), BTreeSet::new())
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &'_ FileInfo> + ExactSizeIterator + DoubleEndedIterator + std::iter::FusedIterator + '_
{
self.1.iter().map(|x| &x.inner().file)
}
#[inline]
pub fn into_iter(self) -> impl Iterator<Item = FileInfo> + ExactSizeIterator + DoubleEndedIterator + std::iter::FusedIterator + 'static
{
self.1.into_iter().map(|x| x.into_inner().file)
}
#[inline]
pub fn insert(&mut self, parent: impl Into<Option<FileInfo>>, file: FileInfo)
{
self.1.insert(order::Ordered::new(NestedFileInfo::new(parent.into(), file)));
}
#[inline]
pub fn len(&self) -> usize
{
self.1.len()
}
}
impl FSTimeMap
{
#[inline]
@ -154,3 +196,72 @@ impl FSTimeMap
self.1.len()
}
}
/// Tree-maintaining file info
#[derive(Debug, Clone)]
pub struct NestedFileInfo
{
file: FileInfo,
parent: Option<FileInfo>
}
impl NestedFileInfo
{
#[inline]
pub fn new(parent: Option<FileInfo>, file: FileInfo) -> Self
{
Self {
file,
parent,
}
}
#[inline]
pub fn into_inner(self) -> FileInfo
{
self.file
}
#[inline]
pub fn parent(&self) -> Option<&FileInfo>
{
self.parent.as_ref()
}
}
impl order::Orderer<NestedFileInfo> for FileInfo
{
#[inline]
fn order(a: &NestedFileInfo, b: &NestedFileInfo) -> std::cmp::Ordering {
if let Some(parent) = &a.parent {
// Check if `b` is parent of `a`, if so, `a` *always* comes after `b`
if parent.path() == b.file.path() {
return std::cmp::Ordering::Greater;
}
// If `a`'s parent is not the same as `b`'s parent, then `a` always comes *before* `b`.
if let Some(bparent) = &b.parent {
if !FileInfo::order(parent, bparent).is_eq() {
return std::cmp::Ordering::Less;
}
}
}
if let Some(parent) = &b.parent {
// Check if `a` is parent of `b`, if so, `b` *always* comes after `a`.
if parent.path() == a.file.path() {
return std::cmp::Ordering::Less;
}
// If `b`'s parent is not the same as `a`'s parent, then `b` always comes *before* `a`.
if let Some(aparent) = &a.parent {
if !FileInfo::order(parent, aparent).is_eq() {
return std::cmp::Ordering::Greater;
}
}
}
FileInfo::order(&a.file, &b.file)
}
}

Loading…
Cancel
Save