wip: hier walker
ci/woodpecker/push/woodpecker Pipeline failed
Details
ci/woodpecker/push/woodpecker Pipeline failed
Details
parent
f597f0a69a
commit
e5e314186b
|
@ -1042,6 +1042,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.0"
|
||||
|
@ -3202,6 +3208,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"diesel",
|
||||
"diesel_migrations",
|
||||
"fallible-iterator",
|
||||
"filebuffer",
|
||||
"lazy_static",
|
||||
"lexpr",
|
||||
|
|
|
@ -59,6 +59,7 @@ tree_magic_mini = { version = "3.0.2", features = ["with-gpl-data"] }
|
|||
nonempty = "0.6.0"
|
||||
|
||||
shadow-rs = { version = "0.23", default-features = false }
|
||||
fallible-iterator = "0.3.0"
|
||||
|
||||
[build-dependencies]
|
||||
shadow-rs = { version = "0.23", default-features = false }
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use std::collections::HashSet;
|
||||
use std::convert::TryFrom;
|
||||
use std::iter::{self, FromIterator};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use fallible_iterator::FallibleIterator;
|
||||
use lru::LruCache;
|
||||
use tracing::trace;
|
||||
use uuid::Uuid;
|
||||
|
@ -82,6 +85,57 @@ pub fn list_roots(connection: &UpEndConnection) -> Result<Vec<Address>> {
|
|||
.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! {
|
||||
static ref FETCH_CREATE_LOCK: Mutex<()> = Mutex::new(());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue