From c13a1ae2bafa9a94503b08aeecbf1ad4a4eeb488 Mon Sep 17 00:00:00 2001 From: Peter Heringer Date: Thu, 4 Jan 2024 09:30:16 +0100 Subject: [PATCH] Start development of steps --- lib/src/storage/mod.rs | 108 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/lib/src/storage/mod.rs b/lib/src/storage/mod.rs index 4ad3ef5b..d5c155fa 100644 --- a/lib/src/storage/mod.rs +++ b/lib/src/storage/mod.rs @@ -21,11 +21,17 @@ use backend::{ColumnFamily, ColumnFamilyDefinition, Db, Iter}; use gfa::gfa::Orientation; use gfa::parser::GFAParser; use handlegraph::handle::{Direction, Handle}; +use handlegraph::hashgraph::path::StepIx; +use handlegraph::pathhandlegraph::{ + path::PathStep, GraphPaths, GraphPathsRef, IntoPathIds, PathBase, +}; +use handlegraph::pathhandlegraph::{GraphPathNames, PathId}; use handlegraph::{ conversion::from_gfa, handlegraph::IntoHandles, handlegraph::IntoNeighbors, handlegraph::IntoSequences, packedgraph::PackedGraph, }; use oxrdf::{Literal, NamedNode}; +use rio_api::model::NamedNode; use std::str; #[cfg(not(target_family = "wasm"))] @@ -250,6 +256,16 @@ impl StorageReader { }, second: None, }; + } else if self.is_step_associated(predicate) { + println!("Containing node-related predicate"); + let terms = self.steps(subject, predicate, object, graph_name); + return ChainedDecodingQuadIterator { + first: DecodingQuadIterator { + terms, + encoding: QuadEncoding::Spog, + }, + second: None, + }; } return ChainedDecodingQuadIterator { first: DecodingQuadIterator { @@ -332,6 +348,59 @@ impl StorageReader { results } + fn steps( + &self, + subject: Option<&EncodedTerm>, + predicate: Option<&EncodedTerm>, + object: Option<&EncodedTerm>, + graph_name: &EncodedTerm, + ) -> Vec { + let mut results = Vec::new(); + if subject.is_none() { + for path_id in self.storage.graph.path_ids() { + if let Some(path_ref) = self.storage.graph.get_path_ref(path_id) { + let mut rank = 1; + let mut position = 1; + let step_handle = path_ref.step_at(path_ref.first_step()); + if step_handle.is_none() { + continue; + } + let step_handle = step_handle.unwrap(); + let node_handle = step_handle.handle(); + let mut triples = self.step_handle_to_triples( + path_id, + step_handle, + subject, + predicate, + object, + node_handle, + rank, + position, + ); + results.append(&mut triples); + } + } + } + results + } + + fn step_handle_to_triples( + &self, + path_id: PathId, + step_handle: Option, + subject: Option<&EncodedTerm>, + predicate: Option<&EncodedTerm>, + object: Option<&EncodedTerm>, + node_handle: Handle, + rank: u32, + position: u32, + ) -> Vec { + let mut results = Vec::new(); + + if subject.is_none() || self.step_to_namednode(path_id, step_handle.unwrap()) == subject {} + results + } + fn handle_to_triples( &self, subject: &EncodedTerm, @@ -477,6 +546,23 @@ impl StorageReader { Some(named_node.as_ref().into()) } + fn step_to_namednode(&self, path: PathId, step: StepIx) -> Option { + if let Some(path_name_iter) = self.storage.graph.get_path_name(path) { + let path_name: Vec = path_name_iter.collect(); + let path_name = std::str::from_utf8(&path_name).ok()?; + let text = format!( + "{}/path/{}/step/{}", + self.storage.base, + path_name, + step.index()? + ); + let named_node = NamedNode::new(text).unwrap(); + Some(named_node.as_ref().into()) + } else { + None + } + } + fn is_node_related(&self, predicate: Option<&EncodedTerm>) -> bool { let predicates = [ vg::LINKS, @@ -495,6 +581,28 @@ impl StorageReader { .unwrap() } + fn is_step_associated(&self, predicate: Option<&EncodedTerm>) -> bool { + let predicates = [ + vg::RANK, + vg::POSITION, + vg::PATH_PRED, + vg::NODE_PRED, + vg::REVERSE_OF_NODE, + faldo::BEGIN, + faldo::END, + faldo::REFERENCE, + faldo::POSITION_PRED, + ]; + if predicate.is_none() { + return false; + } + predicates + .into_iter() + .map(|x| self.is_vocab(predicate, x)) + .reduce(|acc, x| acc || x) + .unwrap() + } + fn is_vocab(&self, term: Option<&EncodedTerm>, vocab: NamedNodeRef) -> bool { if term.is_none() { return false;