Skip to content

Commit

Permalink
Issue #1 WIP - Used a macro to elminiate duplicate code for trait bla…
Browse files Browse the repository at this point in the history
…nket implementations of &T and Rc<T>. Updated the HDT test driver to open the HDT only once and reuse the dataset instance via Rc<HDTDatasetView>.
  • Loading branch information
donpellegrino committed Oct 14, 2023
1 parent 81f847d commit 11ceefc
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 71 deletions.
37 changes: 25 additions & 12 deletions hdt_driver/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use oxigraph::sparql::dataset::HDTDatasetView;
use oxigraph::sparql::evaluate_hdt_query;
use oxigraph::sparql::QueryOptions;
use oxigraph::sparql::QueryResults;
use std::rc::Rc;

// Run with `cargo run --bin hdt_driver`.

Expand All @@ -11,17 +12,23 @@ use oxigraph::sparql::QueryResults;
fn main() {
println!("Oxigraph/HDT - Driver for Testing");

// Open the HDT file.
let dataset = Rc::new(HDTDatasetView::new("hdt_driver/test.hdt"));

// Test
println!();
println!("Test");
println!();

let dataset1 = HDTDatasetView::new("hdt_driver/test.hdt");
let sparql_query = "SELECT ?o WHERE { <http://example.org/book/book1> ?p ?o }";

let (results, _explain) =
evaluate_hdt_query(dataset1, sparql_query, QueryOptions::default(), false)
.expect("failed to evaluate SPARQL query");
let (results, _explain) = evaluate_hdt_query(
Rc::clone(&dataset),
sparql_query,
QueryOptions::default(),
false,
)
.expect("failed to evaluate SPARQL query");

if let QueryResults::Solutions(solutions) = results.unwrap() {
for solution in solutions {
Expand All @@ -34,12 +41,15 @@ fn main() {
println!("Test");
println!();

let dataset2 = HDTDatasetView::new("hdt_driver/test.hdt");
let sparql_query = "SELECT ?s WHERE { ?s <http://purl.org/dc/elements/1.1/title> ?o }";

let (results, _explain) =
evaluate_hdt_query(dataset2, sparql_query, QueryOptions::default(), false)
.expect("failed to evaluate SPARQL query");
let (results, _explain) = evaluate_hdt_query(
Rc::clone(&dataset),
sparql_query,
QueryOptions::default(),
false,
)
.expect("failed to evaluate SPARQL query");

if let QueryResults::Solutions(solutions) = results.unwrap() {
for solution in solutions {
Expand All @@ -52,12 +62,15 @@ fn main() {
println!("Test");
println!();

let dataset3 = HDTDatasetView::new("hdt_driver/test.hdt");
let sparql_query = "SELECT ?s ?p ?o WHERE { <http://example.org/book/book1> ?p ?o . ?s ?p \"SPARQL Tutorial\" }";

let (results, _explain) =
evaluate_hdt_query(dataset3, sparql_query, QueryOptions::default(), false)
.expect("failed to evaluate SPARQL query");
let (results, _explain) = evaluate_hdt_query(
Rc::clone(&dataset),
sparql_query,
QueryOptions::default(),
false,
)
.expect("failed to evaluate SPARQL query");

if let QueryResults::Solutions(solutions) = results.unwrap() {
for solution in solutions {
Expand Down
102 changes: 45 additions & 57 deletions lib/src/sparql/dataset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,65 +40,53 @@ pub trait DatasetView: Clone {
fn insert_str(&self, key: &StrHash, value: &str);
}

/// Blanket implementation for references to DatasetView.
impl<T: DatasetView> DatasetView for &T {
// Implementation based on
//
// Gjengset, Jon. 2022. “Ergonomic Trait Implementations.” In Rust
// for Rustaceans, 40–40. San Francisco, CA: No Starch Press.
//
// Smith, Mark. 2023. “Rust Trait Implementations and References.”
// Judy2k’s Blog (blog). February 22,
// 2023. https://www.judy.co.uk/blog/rust-traits-and-references/.

fn encoded_quads_for_pattern(
&self,
subject: Option<&EncodedTerm>,
predicate: Option<&EncodedTerm>,
object: Option<&EncodedTerm>,
graph_name: Option<&EncodedTerm>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad, EvaluationError>>> {
return (**self).encoded_quads_for_pattern(subject, predicate, object, graph_name);
}

fn encode_term<'a>(&self, term: impl Into<TermRef<'a>>) -> EncodedTerm {
return (**self).encode_term(term);
}

fn insert_str(&self, key: &StrHash, value: &str) {
return (**self).insert_str(key, value);
}
}

/// Blanket implementation for Rc<T> references to DatasetView.
impl<T: DatasetView> DatasetView for Rc<T> {
// Implementation based on
//
// Gjengset, Jon. 2022. “Ergonomic Trait Implementations.” In Rust
// for Rustaceans, 40–40. San Francisco, CA: No Starch Press.
//
// Smith, Mark. 2023. “Rust Trait Implementations and References.”
// Judy2k’s Blog (blog). February 22,
// 2023. https://www.judy.co.uk/blog/rust-traits-and-references/.

fn encoded_quads_for_pattern(
&self,
subject: Option<&EncodedTerm>,
predicate: Option<&EncodedTerm>,
object: Option<&EncodedTerm>,
graph_name: Option<&EncodedTerm>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad, EvaluationError>>> {
return (**self).encoded_quads_for_pattern(subject, predicate, object, graph_name);
}
my_impl_for! { &T, Rc<T> }
// where
macro_rules! my_impl_for {(
/* macro input */
$( // <---------+ repetition operator,
$Type:ty // | of `:ty`pes, that shall be named with the `$Type` "metavariable"
),* $(,)? // <--+ `,`-separated, with an optional trailing `,`
) => (
/* macro output */
$( // <- for each of the occurrences in input, emit:
/// Blanket implementation for references to DatasetView.
impl<T: DatasetView> DatasetView for $Type {
// Implementation based on
//
// Gjengset, Jon. 2022. “Ergonomic Trait Implementations.”
// In Rust for Rustaceans, 40–40. San Francisco, CA: No
// Starch Press.
//
// Smith, Mark. 2023. “Rust Trait Implementations and
// References.” Judy2k’s Blog (blog). February 22,
// 2023. https://www.judy.co.uk/blog/rust-traits-and-references/.
//
// Note that
// https://docs.rs/syntactic-for/latest/syntactic_for/#impl-blocks
// does not work with the Rc<T> syntax.

fn encoded_quads_for_pattern(
&self,
subject: Option<&EncodedTerm>,
predicate: Option<&EncodedTerm>,
object: Option<&EncodedTerm>,
graph_name: Option<&EncodedTerm>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad, EvaluationError>>> {
return (**self).encoded_quads_for_pattern(subject, predicate, object, graph_name);
}

fn encode_term<'a>(&self, term: impl Into<TermRef<'a>>) -> EncodedTerm {
return (**self).encode_term(term);
}
fn encode_term<'a>(&self, term: impl Into<TermRef<'a>>) -> EncodedTerm {
return (**self).encode_term(term);
}

fn insert_str(&self, key: &StrHash, value: &str) {
return (**self).insert_str(key, value);
}
}
fn insert_str(&self, key: &StrHash, value: &str) {
return (**self).insert_str(key, value);
}
}
)*
)}
use my_impl_for;

/// Boundry over a Header-Dictionary-Triplies (HDT) storage layer.
pub struct HDTDatasetView {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/sparql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use std::time::Duration;
use std::{fmt, io};

pub fn evaluate_hdt_query(
dataset: HDTDatasetView,
dataset: Rc<HDTDatasetView>,
query: impl TryInto<Query, Error = impl Into<EvaluationError>>,
options: QueryOptions,
run_stats: bool,
Expand All @@ -55,7 +55,7 @@ pub fn evaluate_hdt_query(
)?;
let planning_duration = start_planning.elapsed();
let (results, explanation) = SimpleEvaluator::new(
Rc::new(dataset),
Rc::clone(&dataset),
base_iri.map(Rc::new),
options.service_handler(),
Rc::new(options.custom_functions),
Expand Down

0 comments on commit 11ceefc

Please sign in to comment.