Compare commits
1 commit
main
...
feat/hier-
Author | SHA1 | Date | |
---|---|---|---|
e5e314186b |
3 changed files with 62 additions and 0 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -1042,6 +1042,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-iterator"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
@ -3202,6 +3208,7 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel_migrations",
|
"diesel_migrations",
|
||||||
|
"fallible-iterator",
|
||||||
"filebuffer",
|
"filebuffer",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lexpr",
|
"lexpr",
|
||||||
|
|
|
@ -59,6 +59,7 @@ tree_magic_mini = { version = "3.0.2", features = ["with-gpl-data"] }
|
||||||
nonempty = "0.6.0"
|
nonempty = "0.6.0"
|
||||||
|
|
||||||
shadow-rs = { version = "0.23", default-features = false }
|
shadow-rs = { version = "0.23", default-features = false }
|
||||||
|
fallible-iterator = "0.3.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
shadow-rs = { version = "0.23", default-features = false }
|
shadow-rs = { version = "0.23", default-features = false }
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::iter::{self, FromIterator};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use fallible_iterator::FallibleIterator;
|
||||||
use lru::LruCache;
|
use lru::LruCache;
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -82,6 +85,57 @@ pub fn list_roots(connection: &UpEndConnection) -> Result<Vec<Address>> {
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type AddressPath = (Vec<Address>, Address);
|
||||||
|
|
||||||
|
pub struct HierWalker {
|
||||||
|
connection: UpEndConnection,
|
||||||
|
current: Vec<AddressPath>,
|
||||||
|
seen: HashSet<Address>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HierWalker {
|
||||||
|
pub fn new(connection: UpEndConnection, start: Address) -> Self {
|
||||||
|
Self {
|
||||||
|
connection,
|
||||||
|
current: vec![(vec![], start.clone())],
|
||||||
|
seen: HashSet::from_iter(iter::once(start)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FallibleIterator for HierWalker {
|
||||||
|
type Item = AddressPath;
|
||||||
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Result<Option<Self::Item>, Self::Error> {
|
||||||
|
while let Some((path, address)) = self.current.pop() {
|
||||||
|
let children: Vec<Address> = self
|
||||||
|
.connection
|
||||||
|
.query(Query::SingleQuery(QueryPart::Matches(PatternQuery {
|
||||||
|
entity: QueryComponent::Variable(None),
|
||||||
|
attribute: QueryComponent::Exact(ATTR_IN.into()),
|
||||||
|
value: QueryComponent::Exact(address.clone().into()),
|
||||||
|
})))?
|
||||||
|
.into_iter()
|
||||||
|
.map(|e| e.entity)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let path: Vec<Address> = path.into_iter().chain(iter::once(address.clone())).collect();
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if !self.seen.contains(&child) {
|
||||||
|
self.seen.insert(child.clone());
|
||||||
|
self.current.push((path.clone(), child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(Some((path, address)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref FETCH_CREATE_LOCK: Mutex<()> = Mutex::new(());
|
static ref FETCH_CREATE_LOCK: Mutex<()> = Mutex::new(());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue