Makes SPARQL query result Send and Sync

pull/692/head
Tpt 11 months ago committed by Thomas Tanon
parent 4f404ab650
commit 899e553249
  1. 3
      lib/sparesults/src/csv.rs
  2. 13
      lib/sparesults/src/parser.rs
  3. 7
      lib/sparesults/src/solution.rs
  4. 27
      lib/src/sparql/eval.rs
  5. 30
      lib/src/sparql/mod.rs
  6. 20
      lib/src/sparql/model.rs
  7. 2
      lib/src/sparql/service.rs
  8. 3
      lib/src/sparql/update.rs
  9. 8
      lib/src/storage/numeric_encoder.rs

@ -628,7 +628,6 @@ mod tests {
use super::*; use super::*;
use std::error::Error; use std::error::Error;
use std::rc::Rc;
fn build_example() -> (Vec<Variable>, Vec<Vec<Option<Term>>>) { fn build_example() -> (Vec<Variable>, Vec<Vec<Option<Term>>>) {
( (
@ -682,7 +681,6 @@ mod tests {
let (variables, solutions) = build_example(); let (variables, solutions) = build_example();
let mut buffer = String::new(); let mut buffer = String::new();
let writer = InnerCsvSolutionsWriter::start(&mut buffer, variables.clone()); let writer = InnerCsvSolutionsWriter::start(&mut buffer, variables.clone());
let variables = Rc::new(variables);
for solution in solutions { for solution in solutions {
writer.write( writer.write(
&mut buffer, &mut buffer,
@ -702,7 +700,6 @@ mod tests {
// Write // Write
let mut buffer = String::new(); let mut buffer = String::new();
let writer = InnerTsvSolutionsWriter::start(&mut buffer, variables.clone()); let writer = InnerTsvSolutionsWriter::start(&mut buffer, variables.clone());
let variables = Rc::new(variables);
for solution in &solutions { for solution in &solutions {
writer.write( writer.write(
&mut buffer, &mut buffer,

@ -6,7 +6,7 @@ use crate::solution::QuerySolution;
use crate::xml::{XmlQueryResultsReader, XmlSolutionsReader}; use crate::xml::{XmlQueryResultsReader, XmlSolutionsReader};
use oxrdf::Variable; use oxrdf::Variable;
use std::io::Read; use std::io::Read;
use std::rc::Rc; use std::sync::Arc;
/// Parsers for [SPARQL query](https://www.w3.org/TR/sparql11-query/) results serialization formats. /// Parsers for [SPARQL query](https://www.w3.org/TR/sparql11-query/) results serialization formats.
/// ///
@ -81,7 +81,7 @@ impl QueryResultsParser {
solutions, solutions,
variables, variables,
} => FromReadQueryResultsReader::Solutions(FromReadSolutionsReader { } => FromReadQueryResultsReader::Solutions(FromReadSolutionsReader {
variables: Rc::new(variables), variables: variables.into(),
solutions: SolutionsReaderKind::Xml(solutions), solutions: SolutionsReaderKind::Xml(solutions),
}), }),
}, },
@ -91,7 +91,7 @@ impl QueryResultsParser {
solutions, solutions,
variables, variables,
} => FromReadQueryResultsReader::Solutions(FromReadSolutionsReader { } => FromReadQueryResultsReader::Solutions(FromReadSolutionsReader {
variables: Rc::new(variables), variables: variables.into(),
solutions: SolutionsReaderKind::Json(solutions), solutions: SolutionsReaderKind::Json(solutions),
}), }),
}, },
@ -102,7 +102,7 @@ impl QueryResultsParser {
solutions, solutions,
variables, variables,
} => FromReadQueryResultsReader::Solutions(FromReadSolutionsReader { } => FromReadQueryResultsReader::Solutions(FromReadSolutionsReader {
variables: Rc::new(variables), variables: variables.into(),
solutions: SolutionsReaderKind::Tsv(solutions), solutions: SolutionsReaderKind::Tsv(solutions),
}), }),
}, },
@ -166,9 +166,8 @@ pub enum FromReadQueryResultsReader<R: Read> {
/// } /// }
/// # Result::<(),sparesults::ParseError>::Ok(()) /// # Result::<(),sparesults::ParseError>::Ok(())
/// ``` /// ```
#[allow(clippy::rc_buffer)]
pub struct FromReadSolutionsReader<R: Read> { pub struct FromReadSolutionsReader<R: Read> {
variables: Rc<Vec<Variable>>, variables: Arc<[Variable]>,
solutions: SolutionsReaderKind<R>, solutions: SolutionsReaderKind<R>,
} }
@ -209,7 +208,7 @@ impl<R: Read> Iterator for FromReadSolutionsReader<R> {
SolutionsReaderKind::Tsv(reader) => reader.read_next(), SolutionsReaderKind::Tsv(reader) => reader.read_next(),
} }
.transpose()? .transpose()?
.map(|values| (Rc::clone(&self.variables), values).into()), .map(|values| (Arc::clone(&self.variables), values).into()),
) )
} }
} }

@ -4,7 +4,7 @@ use oxrdf::{Term, Variable, VariableRef};
use std::fmt; use std::fmt;
use std::iter::Zip; use std::iter::Zip;
use std::ops::Index; use std::ops::Index;
use std::rc::Rc; use std::sync::Arc;
/// Tuple associating variables and terms that are the result of a SPARQL query. /// Tuple associating variables and terms that are the result of a SPARQL query.
/// ///
@ -18,9 +18,8 @@ use std::rc::Rc;
/// assert_eq!(solution.get("foo"), Some(&Literal::from(1).into())); // Get the value of the variable ?foo if it exists (here yes). /// assert_eq!(solution.get("foo"), Some(&Literal::from(1).into())); // Get the value of the variable ?foo if it exists (here yes).
/// assert_eq!(solution.get(1), None); // Get the value of the second column if it exists (here no). /// assert_eq!(solution.get(1), None); // Get the value of the second column if it exists (here no).
/// ``` /// ```
#[allow(clippy::rc_buffer)]
pub struct QuerySolution { pub struct QuerySolution {
variables: Rc<Vec<Variable>>, variables: Arc<[Variable]>,
values: Vec<Option<Term>>, values: Vec<Option<Term>>,
} }
@ -116,7 +115,7 @@ impl QuerySolution {
} }
} }
impl<V: Into<Rc<Vec<Variable>>>, S: Into<Vec<Option<Term>>>> From<(V, S)> for QuerySolution { impl<V: Into<Arc<[Variable]>>, S: Into<Vec<Option<Term>>>> From<(V, S)> for QuerySolution {
#[inline] #[inline]
fn from((v, s): (V, S)) -> Self { fn from((v, s): (V, S)) -> Self {
Self { Self {

@ -1,10 +1,11 @@
use crate::model::vocab::{rdf, xsd}; use crate::model::vocab::{rdf, xsd};
use crate::model::{BlankNode, LiteralRef, NamedNode, NamedNodeRef, Term, Triple}; use crate::model::{BlankNode, LiteralRef, NamedNodeRef, Term, Triple};
use crate::sparql::algebra::{Query, QueryDataset}; use crate::sparql::algebra::{Query, QueryDataset};
use crate::sparql::dataset::DatasetView; use crate::sparql::dataset::DatasetView;
use crate::sparql::error::EvaluationError; use crate::sparql::error::EvaluationError;
use crate::sparql::model::*; use crate::sparql::model::*;
use crate::sparql::service::ServiceHandler; use crate::sparql::service::ServiceHandler;
use crate::sparql::CustomFunctionRegistry;
use crate::storage::numeric_encoder::*; use crate::storage::numeric_encoder::*;
use crate::storage::small_string::SmallString; use crate::storage::small_string::SmallString;
use digest::Digest; use digest::Digest;
@ -35,6 +36,7 @@ use std::hash::{Hash, Hasher};
use std::iter::Iterator; use std::iter::Iterator;
use std::iter::{empty, once}; use std::iter::{empty, once};
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
use std::{fmt, io, str}; use std::{fmt, io, str};
const REGEX_SIZE_LIMIT: usize = 1_000_000; const REGEX_SIZE_LIMIT: usize = 1_000_000;
@ -119,15 +121,14 @@ impl IntoIterator for EncodedTuple {
} }
type EncodedTuplesIterator = Box<dyn Iterator<Item = Result<EncodedTuple, EvaluationError>>>; type EncodedTuplesIterator = Box<dyn Iterator<Item = Result<EncodedTuple, EvaluationError>>>;
type CustomFunctionRegistry = HashMap<NamedNode, Rc<dyn Fn(&[Term]) -> Option<Term>>>;
#[derive(Clone)] #[derive(Clone)]
pub struct SimpleEvaluator { pub struct SimpleEvaluator {
dataset: Rc<DatasetView>, dataset: Rc<DatasetView>,
base_iri: Option<Rc<Iri<String>>>, base_iri: Option<Rc<Iri<String>>>,
now: DateTime, now: DateTime,
service_handler: Rc<dyn ServiceHandler<Error = EvaluationError>>, service_handler: Arc<dyn ServiceHandler<Error = EvaluationError>>,
custom_functions: Rc<CustomFunctionRegistry>, custom_functions: Arc<CustomFunctionRegistry>,
run_stats: bool, run_stats: bool,
} }
@ -135,8 +136,8 @@ impl SimpleEvaluator {
pub fn new( pub fn new(
dataset: Rc<DatasetView>, dataset: Rc<DatasetView>,
base_iri: Option<Rc<Iri<String>>>, base_iri: Option<Rc<Iri<String>>>,
service_handler: Rc<dyn ServiceHandler<Error = EvaluationError>>, service_handler: Arc<dyn ServiceHandler<Error = EvaluationError>>,
custom_functions: Rc<CustomFunctionRegistry>, custom_functions: Arc<CustomFunctionRegistry>,
run_stats: bool, run_stats: bool,
) -> Self { ) -> Self {
Self { Self {
@ -149,7 +150,6 @@ impl SimpleEvaluator {
} }
} }
#[allow(clippy::rc_buffer)]
pub fn evaluate_select(&self, pattern: &GraphPattern) -> (QueryResults, Rc<EvalNodeWithStats>) { pub fn evaluate_select(&self, pattern: &GraphPattern) -> (QueryResults, Rc<EvalNodeWithStats>) {
let mut variables = Vec::new(); let mut variables = Vec::new();
let (eval, stats) = self.graph_pattern_evaluator(pattern, &mut variables); let (eval, stats) = self.graph_pattern_evaluator(pattern, &mut variables);
@ -158,7 +158,7 @@ impl SimpleEvaluator {
QueryResults::Solutions(decode_bindings( QueryResults::Solutions(decode_bindings(
Rc::clone(&self.dataset), Rc::clone(&self.dataset),
eval(from), eval(from),
Rc::from(variables), Arc::from(variables),
)), )),
stats, stats,
) )
@ -3127,11 +3127,10 @@ pub(super) fn compile_pattern(pattern: &str, flags: Option<&str>) -> Option<Rege
regex_builder.build().ok() regex_builder.build().ok()
} }
#[allow(clippy::rc_buffer)]
fn decode_bindings( fn decode_bindings(
dataset: Rc<DatasetView>, dataset: Rc<DatasetView>,
iter: EncodedTuplesIterator, iter: EncodedTuplesIterator,
variables: Rc<Vec<Variable>>, variables: Arc<[Variable]>,
) -> QuerySolutionIter { ) -> QuerySolutionIter {
let tuple_size = variables.len(); let tuple_size = variables.len();
QuerySolutionIter::new( QuerySolutionIter::new(
@ -3223,15 +3222,15 @@ fn equals(a: &EncodedTerm, b: &EncodedTerm) -> Option<bool> {
EncodedTerm::FloatLiteral(a) => match b { EncodedTerm::FloatLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => Some(a == b), EncodedTerm::FloatLiteral(b) => Some(a == b),
EncodedTerm::DoubleLiteral(b) => Some(Double::from(*a) == *b), EncodedTerm::DoubleLiteral(b) => Some(Double::from(*a) == *b),
EncodedTerm::IntegerLiteral(b) => Some(*a == Float::from(*b)), EncodedTerm::IntegerLiteral(b) => Some(*a == (*b).into()),
EncodedTerm::DecimalLiteral(b) => Some(*a == (*b).into()), EncodedTerm::DecimalLiteral(b) => Some(*a == (*b).into()),
_ if b.is_unknown_typed_literal() => None, _ if b.is_unknown_typed_literal() => None,
_ => Some(false), _ => Some(false),
}, },
EncodedTerm::DoubleLiteral(a) => match b { EncodedTerm::DoubleLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => Some(*a == Double::from(*b)), EncodedTerm::FloatLiteral(b) => Some(*a == (*b).into()),
EncodedTerm::DoubleLiteral(b) => Some(a == b), EncodedTerm::DoubleLiteral(b) => Some(a == b),
EncodedTerm::IntegerLiteral(b) => Some(*a == Double::from(*b)), EncodedTerm::IntegerLiteral(b) => Some(*a == (*b).into()),
EncodedTerm::DecimalLiteral(b) => Some(*a == (*b).into()), EncodedTerm::DecimalLiteral(b) => Some(*a == (*b).into()),
_ if b.is_unknown_typed_literal() => None, _ if b.is_unknown_typed_literal() => None,
_ => Some(false), _ => Some(false),
@ -3247,7 +3246,7 @@ fn equals(a: &EncodedTerm, b: &EncodedTerm) -> Option<bool> {
EncodedTerm::DecimalLiteral(a) => match b { EncodedTerm::DecimalLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => Some(Float::from(*a) == *b), EncodedTerm::FloatLiteral(b) => Some(Float::from(*a) == *b),
EncodedTerm::DoubleLiteral(b) => Some(Double::from(*a) == *b), EncodedTerm::DoubleLiteral(b) => Some(Double::from(*a) == *b),
EncodedTerm::IntegerLiteral(b) => Some(*a == Decimal::from(*b)), EncodedTerm::IntegerLiteral(b) => Some(*a == (*b).into()),
EncodedTerm::DecimalLiteral(b) => Some(a == b), EncodedTerm::DecimalLiteral(b) => Some(a == b),
_ if b.is_unknown_typed_literal() => None, _ if b.is_unknown_typed_literal() => None,
_ => Some(false), _ => Some(false),

@ -30,6 +30,7 @@ use sparopt::algebra::GraphPattern;
use sparopt::Optimizer; use sparopt::Optimizer;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use std::{fmt, io}; use std::{fmt, io};
@ -56,7 +57,7 @@ pub(crate) fn evaluate_query(
Rc::new(dataset), Rc::new(dataset),
base_iri.map(Rc::new), base_iri.map(Rc::new),
options.service_handler(), options.service_handler(),
Rc::new(options.custom_functions), Arc::new(options.custom_functions),
run_stats, run_stats,
) )
.evaluate_select(&pattern); .evaluate_select(&pattern);
@ -76,7 +77,7 @@ pub(crate) fn evaluate_query(
Rc::new(dataset), Rc::new(dataset),
base_iri.map(Rc::new), base_iri.map(Rc::new),
options.service_handler(), options.service_handler(),
Rc::new(options.custom_functions), Arc::new(options.custom_functions),
run_stats, run_stats,
) )
.evaluate_ask(&pattern); .evaluate_ask(&pattern);
@ -99,7 +100,7 @@ pub(crate) fn evaluate_query(
Rc::new(dataset), Rc::new(dataset),
base_iri.map(Rc::new), base_iri.map(Rc::new),
options.service_handler(), options.service_handler(),
Rc::new(options.custom_functions), Arc::new(options.custom_functions),
run_stats, run_stats,
) )
.evaluate_construct(&pattern, &template); .evaluate_construct(&pattern, &template);
@ -119,7 +120,7 @@ pub(crate) fn evaluate_query(
Rc::new(dataset), Rc::new(dataset),
base_iri.map(Rc::new), base_iri.map(Rc::new),
options.service_handler(), options.service_handler(),
Rc::new(options.custom_functions), Arc::new(options.custom_functions),
run_stats, run_stats,
) )
.evaluate_describe(&pattern); .evaluate_describe(&pattern);
@ -155,19 +156,22 @@ pub(crate) fn evaluate_query(
/// ``` /// ```
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct QueryOptions { pub struct QueryOptions {
service_handler: Option<Rc<dyn ServiceHandler<Error = EvaluationError>>>, service_handler: Option<Arc<dyn ServiceHandler<Error = EvaluationError>>>,
custom_functions: HashMap<NamedNode, Rc<dyn Fn(&[Term]) -> Option<Term>>>, custom_functions: CustomFunctionRegistry,
http_timeout: Option<Duration>, http_timeout: Option<Duration>,
http_redirection_limit: usize, http_redirection_limit: usize,
without_optimizations: bool, without_optimizations: bool,
} }
pub(crate) type CustomFunctionRegistry =
HashMap<NamedNode, Arc<dyn (Fn(&[Term]) -> Option<Term>) + Send + Sync>>;
impl QueryOptions { impl QueryOptions {
/// Use a given [`ServiceHandler`] to execute [SPARQL 1.1 Federated Query](https://www.w3.org/TR/sparql11-federated-query/) SERVICE calls. /// Use a given [`ServiceHandler`] to execute [SPARQL 1.1 Federated Query](https://www.w3.org/TR/sparql11-federated-query/) SERVICE calls.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn with_service_handler(mut self, service_handler: impl ServiceHandler + 'static) -> Self { pub fn with_service_handler(mut self, service_handler: impl ServiceHandler + 'static) -> Self {
self.service_handler = Some(Rc::new(ErrorConversionServiceHandler::wrap( self.service_handler = Some(Arc::new(ErrorConversionServiceHandler::wrap(
service_handler, service_handler,
))); )));
self self
@ -177,7 +181,7 @@ impl QueryOptions {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn without_service_handler(mut self) -> Self { pub fn without_service_handler(mut self) -> Self {
self.service_handler = Some(Rc::new(EmptyServiceHandler)); self.service_handler = Some(Arc::new(EmptyServiceHandler));
self self
} }
@ -227,21 +231,21 @@ impl QueryOptions {
pub fn with_custom_function( pub fn with_custom_function(
mut self, mut self,
name: NamedNode, name: NamedNode,
evaluator: impl Fn(&[Term]) -> Option<Term> + 'static, evaluator: impl Fn(&[Term]) -> Option<Term> + Send + Sync + 'static,
) -> Self { ) -> Self {
self.custom_functions.insert(name, Rc::new(evaluator)); self.custom_functions.insert(name, Arc::new(evaluator));
self self
} }
fn service_handler(&self) -> Rc<dyn ServiceHandler<Error = EvaluationError>> { fn service_handler(&self) -> Arc<dyn ServiceHandler<Error = EvaluationError>> {
self.service_handler.clone().unwrap_or_else(|| { self.service_handler.clone().unwrap_or_else(|| {
if cfg!(feature = "http-client") { if cfg!(feature = "http-client") {
Rc::new(service::SimpleServiceHandler::new( Arc::new(service::SimpleServiceHandler::new(
self.http_timeout, self.http_timeout,
self.http_redirection_limit, self.http_redirection_limit,
)) ))
} else { } else {
Rc::new(EmptyServiceHandler) Arc::new(EmptyServiceHandler)
} }
}) })
} }

@ -8,7 +8,7 @@ use crate::sparql::results::{
use oxrdf::{Variable, VariableRef}; use oxrdf::{Variable, VariableRef};
pub use sparesults::QuerySolution; pub use sparesults::QuerySolution;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::rc::Rc; use std::sync::Arc;
/// Results of a [SPARQL query](https://www.w3.org/TR/sparql11-query/). /// Results of a [SPARQL query](https://www.w3.org/TR/sparql11-query/).
pub enum QueryResults { pub enum QueryResults {
@ -170,22 +170,20 @@ impl<R: Read + 'static> From<FromReadQueryResultsReader<R>> for QueryResults {
/// } /// }
/// # Result::<_,Box<dyn std::error::Error>>::Ok(()) /// # Result::<_,Box<dyn std::error::Error>>::Ok(())
/// ``` /// ```
#[allow(clippy::rc_buffer)]
pub struct QuerySolutionIter { pub struct QuerySolutionIter {
variables: Rc<Vec<Variable>>, variables: Arc<[Variable]>,
iter: Box<dyn Iterator<Item = Result<QuerySolution, EvaluationError>>>, iter: Box<dyn Iterator<Item = Result<QuerySolution, EvaluationError>>>,
} }
impl QuerySolutionIter { impl QuerySolutionIter {
#[allow(clippy::rc_buffer)]
pub fn new( pub fn new(
variables: Rc<Vec<Variable>>, variables: Arc<[Variable]>,
iter: impl Iterator<Item = Result<Vec<Option<Term>>, EvaluationError>> + 'static, iter: impl Iterator<Item = Result<Vec<Option<Term>>, EvaluationError>> + 'static,
) -> Self { ) -> Self {
Self { Self {
variables: Rc::clone(&variables), variables: Arc::clone(&variables),
iter: Box::new( iter: Box::new(
iter.map(move |t| t.map(|values| (Rc::clone(&variables), values).into())), iter.map(move |t| t.map(|values| (Arc::clone(&variables), values).into())),
), ),
} }
} }
@ -211,7 +209,7 @@ impl QuerySolutionIter {
impl<R: Read + 'static> From<FromReadSolutionsReader<R>> for QuerySolutionIter { impl<R: Read + 'static> From<FromReadSolutionsReader<R>> for QuerySolutionIter {
fn from(reader: FromReadSolutionsReader<R>) -> Self { fn from(reader: FromReadSolutionsReader<R>) -> Self {
Self { Self {
variables: Rc::new(reader.variables().to_vec()), variables: reader.variables().into(),
iter: Box::new(reader.map(|t| t.map_err(EvaluationError::from))), iter: Box::new(reader.map(|t| t.map_err(EvaluationError::from))),
} }
} }
@ -291,10 +289,12 @@ mod tests {
QueryResults::Boolean(true), QueryResults::Boolean(true),
QueryResults::Boolean(false), QueryResults::Boolean(false),
QueryResults::Solutions(QuerySolutionIter::new( QueryResults::Solutions(QuerySolutionIter::new(
Rc::new(vec![ [
Variable::new_unchecked("foo"), Variable::new_unchecked("foo"),
Variable::new_unchecked("bar"), Variable::new_unchecked("bar"),
]), ]
.as_ref()
.into(),
Box::new( Box::new(
vec![ vec![
Ok(vec![None, None]), Ok(vec![None, None]),

@ -48,7 +48,7 @@ use std::time::Duration;
/// } /// }
/// # Result::<_,Box<dyn std::error::Error>>::Ok(()) /// # Result::<_,Box<dyn std::error::Error>>::Ok(())
/// ``` /// ```
pub trait ServiceHandler { pub trait ServiceHandler: Send + Sync {
type Error: Error + Send + Sync + 'static; type Error: Error + Send + Sync + 'static;
/// Evaluates a [`Query`] against a given service identified by a [`NamedNode`]. /// Evaluates a [`Query`] against a given service identified by a [`NamedNode`].

@ -19,6 +19,7 @@ use sparopt::Optimizer;
use std::collections::HashMap; use std::collections::HashMap;
use std::io; use std::io;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
pub fn evaluate_update<'a, 'b: 'a>( pub fn evaluate_update<'a, 'b: 'a>(
transaction: &'a mut StorageWriter<'b>, transaction: &'a mut StorageWriter<'b>,
@ -131,7 +132,7 @@ impl<'a, 'b: 'a> SimpleUpdateEvaluator<'a, 'b> {
Rc::clone(&dataset), Rc::clone(&dataset),
self.base_iri.clone(), self.base_iri.clone(),
self.options.query_options.service_handler(), self.options.query_options.service_handler(),
Rc::new(self.options.query_options.custom_functions.clone()), Arc::new(self.options.query_options.custom_functions.clone()),
false, false,
); );
let mut variables = Vec::new(); let mut variables = Vec::new();

@ -8,8 +8,8 @@ use siphasher::sip128::{Hasher128, SipHasher24};
use std::fmt::Debug; use std::fmt::Debug;
use std::hash::Hash; use std::hash::Hash;
use std::hash::Hasher; use std::hash::Hasher;
use std::rc::Rc;
use std::str; use std::str;
use std::sync::Arc;
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
#[repr(transparent)] #[repr(transparent)]
@ -96,7 +96,7 @@ pub enum EncodedTerm {
DurationLiteral(Duration), DurationLiteral(Duration),
YearMonthDurationLiteral(YearMonthDuration), YearMonthDurationLiteral(YearMonthDuration),
DayTimeDurationLiteral(DayTimeDuration), DayTimeDurationLiteral(DayTimeDuration),
Triple(Rc<EncodedTriple>), Triple(Arc<EncodedTriple>),
} }
impl PartialEq for EncodedTerm { impl PartialEq for EncodedTerm {
@ -471,7 +471,7 @@ impl From<DayTimeDuration> for EncodedTerm {
impl From<EncodedTriple> for EncodedTerm { impl From<EncodedTriple> for EncodedTerm {
fn from(value: EncodedTriple) -> Self { fn from(value: EncodedTriple) -> Self {
Self::Triple(Rc::new(value)) Self::Triple(Arc::new(value))
} }
} }
@ -634,7 +634,7 @@ impl From<GraphNameRef<'_>> for EncodedTerm {
impl From<TripleRef<'_>> for EncodedTerm { impl From<TripleRef<'_>> for EncodedTerm {
fn from(triple: TripleRef<'_>) -> Self { fn from(triple: TripleRef<'_>) -> Self {
Self::Triple(Rc::new(triple.into())) Self::Triple(Arc::new(triple.into()))
} }
} }

Loading…
Cancel
Save