Drops generics on string ids

pull/171/head
Tpt 4 years ago
parent 7280823444
commit fe5bab8eb9
  1. 221
      lib/src/sparql/dataset.rs
  2. 404
      lib/src/sparql/eval.rs
  3. 2
      lib/src/sparql/mod.rs
  4. 306
      lib/src/sparql/plan.rs
  5. 66
      lib/src/sparql/plan_builder.rs
  6. 73
      lib/src/sparql/update.rs
  7. 5
      lib/src/store/binary_encoder.rs
  8. 48
      lib/src/store/mod.rs
  9. 367
      lib/src/store/numeric_encoder.rs
  10. 6
      lib/src/store/sled.rs

@ -1,8 +1,7 @@
use crate::sparql::algebra::QueryDataset; use crate::sparql::algebra::QueryDataset;
use crate::sparql::EvaluationError; use crate::sparql::EvaluationError;
use crate::store::numeric_encoder::{ use crate::store::numeric_encoder::{
EncodedQuad, EncodedTerm, ReadEncoder, StrContainer, StrEncodingAware, StrHash, StrId, EncodedQuad, EncodedTerm, ReadEncoder, StrContainer, StrEncodingAware, StrHash, StrLookup,
StrLookup,
}; };
use crate::store::ReadableEncodedStore; use crate::store::ReadableEncodedStore;
use std::cell::RefCell; use std::cell::RefCell;
@ -12,7 +11,7 @@ use std::iter::{empty, once, Once};
pub(crate) struct DatasetView<S: ReadableEncodedStore> { pub(crate) struct DatasetView<S: ReadableEncodedStore> {
store: S, store: S,
extra: RefCell<HashMap<StrHash, String>>, extra: RefCell<HashMap<StrHash, String>>,
dataset: EncodedDatasetSpec<S::StrId>, dataset: EncodedDatasetSpec,
} }
impl<S: ReadableEncodedStore> DatasetView<S> { impl<S: ReadableEncodedStore> DatasetView<S> {
@ -50,27 +49,68 @@ impl<S: ReadableEncodedStore> DatasetView<S> {
}) })
} }
fn store_encoded_quads_for_pattern(
&self,
subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
) -> impl Iterator<Item = Result<EncodedQuad, EvaluationError>> + 'static {
self.store
.encoded_quads_for_pattern(subject, predicate, object, graph_name)
.map(|t| t.map_err(|e| e.into()))
}
}
impl<S: ReadableEncodedStore> StrEncodingAware for DatasetView<S> {
type Error = EvaluationError;
}
impl<S: ReadableEncodedStore> StrLookup for DatasetView<S> {
fn get_str(&self, id: StrHash) -> Result<Option<String>, EvaluationError> {
self.extra
.borrow()
.get(&id)
.cloned()
.map(Ok)
.or_else(|| self.store.get_str(id).map_err(|e| e.into()).transpose())
.transpose()
}
fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, EvaluationError> {
let id = StrHash::new(value);
Ok(if self.extra.borrow().contains_key(&id) {
Some(id)
} else {
self.store.get_str_id(value).map_err(|e| e.into())?
})
}
}
impl<S: ReadableEncodedStore + 'static> ReadableEncodedStore for DatasetView<S> {
type QuadsIter = Box<dyn Iterator<Item = Result<EncodedQuad, EvaluationError>>>;
type GraphsIter = Once<Result<EncodedTerm, EvaluationError>>;
#[allow(clippy::needless_collect)] #[allow(clippy::needless_collect)]
fn encoded_quads_for_pattern_in_dataset( fn encoded_quads_for_pattern(
&self, &self,
subject: Option<EncodedTerm<S::StrId>>, subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm<S::StrId>>, predicate: Option<EncodedTerm>,
object: Option<EncodedTerm<S::StrId>>, object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm<S::StrId>>, graph_name: Option<EncodedTerm>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad<DatasetStrId<S::StrId>>, EvaluationError>>> ) -> Box<dyn Iterator<Item = Result<EncodedQuad, EvaluationError>>> {
{
if let Some(graph_name) = graph_name { if let Some(graph_name) = graph_name {
if graph_name.is_default_graph() { if graph_name.is_default_graph() {
if let Some(default_graph_graphs) = &self.dataset.default { if let Some(default_graph_graphs) = &self.dataset.default {
if default_graph_graphs.len() == 1 { if default_graph_graphs.len() == 1 {
// Single graph optimization // Single graph optimization
Box::new( Box::new(
map_iter(self.store.encoded_quads_for_pattern( self.store_encoded_quads_for_pattern(
subject, subject,
predicate, predicate,
object, object,
Some(default_graph_graphs[0]), Some(default_graph_graphs[0]),
)) )
.map(|quad| { .map(|quad| {
let quad = quad?; let quad = quad?;
Ok(EncodedQuad::new( Ok(EncodedQuad::new(
@ -85,7 +125,7 @@ impl<S: ReadableEncodedStore> DatasetView<S> {
let iters = default_graph_graphs let iters = default_graph_graphs
.iter() .iter()
.map(|graph_name| { .map(|graph_name| {
self.store.encoded_quads_for_pattern( self.store_encoded_quads_for_pattern(
subject, subject,
predicate, predicate,
object, object,
@ -93,7 +133,7 @@ impl<S: ReadableEncodedStore> DatasetView<S> {
) )
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Box::new(map_iter(iters.into_iter().flatten()).map(|quad| { Box::new(iters.into_iter().flatten().map(|quad| {
let quad = quad?; let quad = quad?;
Ok(EncodedQuad::new( Ok(EncodedQuad::new(
quad.subject, quad.subject,
@ -104,10 +144,7 @@ impl<S: ReadableEncodedStore> DatasetView<S> {
})) }))
} }
} else { } else {
Box::new(map_iter( Box::new(self.store_encoded_quads_for_pattern(subject, predicate, object, None))
self.store
.encoded_quads_for_pattern(subject, predicate, object, None),
))
} }
} else if self } else if self
.dataset .dataset
@ -115,12 +152,12 @@ impl<S: ReadableEncodedStore> DatasetView<S> {
.as_ref() .as_ref()
.map_or(true, |d| d.contains(&graph_name)) .map_or(true, |d| d.contains(&graph_name))
{ {
Box::new(map_iter(self.store.encoded_quads_for_pattern( Box::new(self.store_encoded_quads_for_pattern(
subject, subject,
predicate, predicate,
object, object,
Some(graph_name), Some(graph_name),
))) ))
} else { } else {
Box::new(empty()) Box::new(empty())
} }
@ -128,7 +165,7 @@ impl<S: ReadableEncodedStore> DatasetView<S> {
let iters = named_graphs let iters = named_graphs
.iter() .iter()
.map(|graph_name| { .map(|graph_name| {
self.store.encoded_quads_for_pattern( self.store_encoded_quads_for_pattern(
subject, subject,
predicate, predicate,
object, object,
@ -136,70 +173,17 @@ impl<S: ReadableEncodedStore> DatasetView<S> {
) )
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Box::new(map_iter(iters.into_iter().flatten())) Box::new(iters.into_iter().flatten())
} else { } else {
Box::new( Box::new(
map_iter( self.store_encoded_quads_for_pattern(subject, predicate, object, None)
self.store .filter(|quad| match quad {
.encoded_quads_for_pattern(subject, predicate, object, None), Err(_) => true,
) Ok(quad) => quad.graph_name != EncodedTerm::DefaultGraph,
.filter(|quad| match quad { }),
Err(_) => true,
Ok(quad) => quad.graph_name != EncodedTerm::DefaultGraph,
}),
) )
} }
} }
}
impl<S: ReadableEncodedStore> StrEncodingAware for DatasetView<S> {
type Error = EvaluationError;
type StrId = DatasetStrId<S::StrId>;
}
impl<S: ReadableEncodedStore> StrLookup for DatasetView<S> {
fn get_str(&self, id: DatasetStrId<S::StrId>) -> Result<Option<String>, EvaluationError> {
match id {
DatasetStrId::Store(id) => self.store.get_str(id).map_err(|e| e.into()),
DatasetStrId::Temporary(id) => Ok(self.extra.borrow().get(&id).cloned()),
}
}
fn get_str_id(&self, value: &str) -> Result<Option<DatasetStrId<S::StrId>>, EvaluationError> {
let id = StrHash::new(value);
if self.extra.borrow().contains_key(&id) {
Ok(Some(DatasetStrId::Temporary(id)))
} else {
Ok(self
.store
.get_str_id(value)
.map_err(|e| e.into())?
.map(DatasetStrId::Store))
}
}
}
impl<S: ReadableEncodedStore> ReadableEncodedStore for DatasetView<S> {
type QuadsIter =
Box<dyn Iterator<Item = Result<EncodedQuad<DatasetStrId<S::StrId>>, EvaluationError>>>;
type GraphsIter = Once<Result<EncodedTerm<DatasetStrId<S::StrId>>, EvaluationError>>;
fn encoded_quads_for_pattern(
&self,
subject: Option<EncodedTerm<Self::StrId>>,
predicate: Option<EncodedTerm<Self::StrId>>,
object: Option<EncodedTerm<Self::StrId>>,
graph_name: Option<EncodedTerm<Self::StrId>>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad<DatasetStrId<S::StrId>>, EvaluationError>>>
{
if let Some((subject, predicate, object, graph_name)) =
try_map_quad_pattern(subject, predicate, object, graph_name)
{
self.encoded_quads_for_pattern_in_dataset(subject, predicate, object, graph_name)
} else {
Box::new(empty())
}
}
fn encoded_named_graphs(&self) -> Self::GraphsIter { fn encoded_named_graphs(&self) -> Self::GraphsIter {
once(Err(EvaluationError::msg( once(Err(EvaluationError::msg(
@ -207,90 +191,29 @@ impl<S: ReadableEncodedStore> ReadableEncodedStore for DatasetView<S> {
))) )))
} }
fn contains_encoded_named_graph( fn contains_encoded_named_graph(&self, _: EncodedTerm) -> Result<bool, EvaluationError> {
&self,
_: EncodedTerm<Self::StrId>,
) -> Result<bool, EvaluationError> {
Err(EvaluationError::msg( Err(EvaluationError::msg(
"Graphs lookup is not implemented by DatasetView", "Graphs lookup is not implemented by DatasetView",
)) ))
} }
} }
fn map_iter<'a, I: StrId>(
iter: impl Iterator<Item = Result<EncodedQuad<I>, impl Into<EvaluationError>>> + 'a,
) -> impl Iterator<Item = Result<EncodedQuad<DatasetStrId<I>>, EvaluationError>> + 'a {
iter.map(|t| {
t.map(|q| EncodedQuad {
subject: q.subject.map_id(DatasetStrId::Store),
predicate: q.predicate.map_id(DatasetStrId::Store),
object: q.object.map_id(DatasetStrId::Store),
graph_name: q.graph_name.map_id(DatasetStrId::Store),
})
.map_err(|e| e.into())
})
}
type QuadPattern<I> = (
Option<EncodedTerm<I>>,
Option<EncodedTerm<I>>,
Option<EncodedTerm<I>>,
Option<EncodedTerm<I>>,
);
fn try_map_quad_pattern<I: StrId>(
subject: Option<EncodedTerm<DatasetStrId<I>>>,
predicate: Option<EncodedTerm<DatasetStrId<I>>>,
object: Option<EncodedTerm<DatasetStrId<I>>>,
graph_name: Option<EncodedTerm<DatasetStrId<I>>>,
) -> Option<QuadPattern<I>> {
Some((
transpose(subject.map(|t| t.try_map_id(unwrap_store_id).ok()))?,
transpose(predicate.map(|t| t.try_map_id(unwrap_store_id).ok()))?,
transpose(object.map(|t| t.try_map_id(unwrap_store_id).ok()))?,
transpose(graph_name.map(|t| t.try_map_id(unwrap_store_id).ok()))?,
))
}
fn transpose<T>(o: Option<Option<T>>) -> Option<Option<T>> {
match o {
Some(Some(v)) => Some(Some(v)),
Some(None) => None,
None => Some(None),
}
}
fn unwrap_store_id<I: StrId>(id: DatasetStrId<I>) -> Result<I, ()> {
match id {
DatasetStrId::Store(id) => Ok(id),
DatasetStrId::Temporary(_) => Err(()),
}
}
impl<'a, S: ReadableEncodedStore> StrContainer for &'a DatasetView<S> { impl<'a, S: ReadableEncodedStore> StrContainer for &'a DatasetView<S> {
fn insert_str(&mut self, value: &str) -> Result<Self::StrId, EvaluationError> { fn insert_str(&mut self, value: &str) -> Result<StrHash, EvaluationError> {
if let Some(id) = self.store.get_str_id(value).map_err(|e| e.into())? { if let Some(hash) = self.store.get_str_id(value).map_err(|e| e.into())? {
Ok(DatasetStrId::Store(id)) Ok(hash)
} else { } else {
let hash = StrHash::new(value); let hash = StrHash::new(value);
self.extra self.extra
.borrow_mut() .borrow_mut()
.entry(hash) .entry(hash)
.or_insert_with(|| value.to_owned()); .or_insert_with(|| value.to_owned());
Ok(DatasetStrId::Temporary(hash)) Ok(hash)
} }
} }
} }
#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)] struct EncodedDatasetSpec {
pub enum DatasetStrId<I: StrId> { default: Option<Vec<EncodedTerm>>,
Store(I), named: Option<Vec<EncodedTerm>>,
Temporary(StrHash),
}
impl<I: StrId> StrId for DatasetStrId<I> {}
struct EncodedDatasetSpec<I: StrId> {
default: Option<Vec<EncodedTerm<I>>>,
named: Option<Vec<EncodedTerm<I>>>,
} }

@ -29,7 +29,7 @@ use std::str;
const REGEX_SIZE_LIMIT: usize = 1_000_000; const REGEX_SIZE_LIMIT: usize = 1_000_000;
type EncodedTuplesIterator<I> = Box<dyn Iterator<Item = Result<EncodedTuple<I>, EvaluationError>>>; type EncodedTuplesIterator = Box<dyn Iterator<Item = Result<EncodedTuple, EvaluationError>>>;
pub(crate) struct SimpleEvaluator<S> { pub(crate) struct SimpleEvaluator<S> {
dataset: Rc<S>, dataset: Rc<S>,
@ -51,7 +51,7 @@ impl<S> Clone for SimpleEvaluator<S> {
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> SimpleEvaluator<S> impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> SimpleEvaluator<S>
where where
for<'a> &'a S: StrContainer<StrId = S::StrId>, for<'a> &'a S: StrContainer,
{ {
pub fn new( pub fn new(
dataset: Rc<S>, dataset: Rc<S>,
@ -68,7 +68,7 @@ where
pub fn evaluate_select_plan( pub fn evaluate_select_plan(
&self, &self,
plan: &PlanNode<S::StrId>, plan: &PlanNode,
variables: Rc<Vec<Variable>>, variables: Rc<Vec<Variable>>,
) -> Result<QueryResults, EvaluationError> { ) -> Result<QueryResults, EvaluationError> {
let iter = self.eval_plan(plan, EncodedTuple::with_capacity(variables.len())); let iter = self.eval_plan(plan, EncodedTuple::with_capacity(variables.len()));
@ -77,10 +77,7 @@ where
)) ))
} }
pub fn evaluate_ask_plan( pub fn evaluate_ask_plan(&self, plan: &PlanNode) -> Result<QueryResults, EvaluationError> {
&self,
plan: &PlanNode<S::StrId>,
) -> Result<QueryResults, EvaluationError> {
let from = EncodedTuple::with_capacity(plan.maybe_bound_variables().len()); let from = EncodedTuple::with_capacity(plan.maybe_bound_variables().len());
match self.eval_plan(plan, from).next() { match self.eval_plan(plan, from).next() {
Some(Ok(_)) => Ok(QueryResults::Boolean(true)), Some(Ok(_)) => Ok(QueryResults::Boolean(true)),
@ -91,8 +88,8 @@ where
pub fn evaluate_construct_plan( pub fn evaluate_construct_plan(
&self, &self,
plan: &PlanNode<S::StrId>, plan: &PlanNode,
template: Vec<TripleTemplate<S::StrId>>, template: Vec<TripleTemplate>,
) -> Result<QueryResults, EvaluationError> { ) -> Result<QueryResults, EvaluationError> {
let from = EncodedTuple::with_capacity(plan.maybe_bound_variables().len()); let from = EncodedTuple::with_capacity(plan.maybe_bound_variables().len());
Ok(QueryResults::Graph(QueryTripleIter { Ok(QueryResults::Graph(QueryTripleIter {
@ -106,10 +103,7 @@ where
})) }))
} }
pub fn evaluate_describe_plan( pub fn evaluate_describe_plan(&self, plan: &PlanNode) -> Result<QueryResults, EvaluationError> {
&self,
plan: &PlanNode<S::StrId>,
) -> Result<QueryResults, EvaluationError> {
let from = EncodedTuple::with_capacity(plan.maybe_bound_variables().len()); let from = EncodedTuple::with_capacity(plan.maybe_bound_variables().len());
Ok(QueryResults::Graph(QueryTripleIter { Ok(QueryResults::Graph(QueryTripleIter {
iter: Box::new(DescribeIterator { iter: Box::new(DescribeIterator {
@ -120,11 +114,7 @@ where
})) }))
} }
pub fn eval_plan( pub fn eval_plan(&self, node: &PlanNode, from: EncodedTuple) -> EncodedTuplesIterator {
&self,
node: &PlanNode<S::StrId>,
from: EncodedTuple<S::StrId>,
) -> EncodedTuplesIterator<S::StrId> {
match node { match node {
PlanNode::Init => Box::new(once(Ok(from))), PlanNode::Init => Box::new(once(Ok(from))),
PlanNode::StaticBindings { tuples } => Box::new(tuples.clone().into_iter().map(Ok)), PlanNode::StaticBindings { tuples } => Box::new(tuples.clone().into_iter().map(Ok)),
@ -208,7 +198,7 @@ where
})) }))
} }
} }
let iter: EncodedTuplesIterator<_> = Box::new(iter.map(move |quad| { let iter: EncodedTuplesIterator = Box::new(iter.map(move |quad| {
let quad = quad?; let quad = quad?;
let mut new_tuple = tuple.clone(); let mut new_tuple = tuple.clone();
put_pattern_value(&subject, quad.subject, &mut new_tuple); put_pattern_value(&subject, quad.subject, &mut new_tuple);
@ -239,7 +229,7 @@ where
if let Some(graph_name) = get_pattern_value(&graph_name, &tuple) { if let Some(graph_name) = get_pattern_value(&graph_name, &tuple) {
graph_name graph_name
} else { } else {
let result: EncodedTuplesIterator<_> = let result: EncodedTuplesIterator =
Box::new(once(Err(EvaluationError::msg( Box::new(once(Err(EvaluationError::msg(
"Unknown graph name is not allowed when evaluating property path", "Unknown graph name is not allowed when evaluating property path",
)))); ))));
@ -443,10 +433,8 @@ where
let key_mapping = key_mapping.clone(); let key_mapping = key_mapping.clone();
let aggregates = aggregates.clone(); let aggregates = aggregates.clone();
let mut errors = Vec::default(); let mut errors = Vec::default();
let mut accumulators_for_group = HashMap::< let mut accumulators_for_group =
Vec<Option<EncodedTerm<S::StrId>>>, HashMap::<Vec<Option<EncodedTerm>>, Vec<Box<dyn Accumulator>>>::default();
Vec<Box<dyn Accumulator<S::StrId>>>,
>::default();
self.eval_plan(child, from) self.eval_plan(child, from)
.filter_map(|result| match result { .filter_map(|result| match result {
Ok(result) => Some(result), Ok(result) => Some(result),
@ -512,11 +500,11 @@ where
fn evaluate_service( fn evaluate_service(
&self, &self,
service_name: &PatternValue<S::StrId>, service_name: &PatternValue,
graph_pattern: &GraphPattern, graph_pattern: &GraphPattern,
variables: Rc<Vec<Variable>>, variables: Rc<Vec<Variable>>,
from: &EncodedTuple<S::StrId>, from: &EncodedTuple,
) -> Result<EncodedTuplesIterator<S::StrId>, EvaluationError> { ) -> Result<EncodedTuplesIterator, EvaluationError> {
if let QueryResults::Solutions(iter) = self.service_handler.handle( if let QueryResults::Solutions(iter) = self.service_handler.handle(
self.dataset.decode_named_node( self.dataset.decode_named_node(
get_pattern_value(service_name, from) get_pattern_value(service_name, from)
@ -540,7 +528,7 @@ where
&self, &self,
function: &PlanAggregationFunction, function: &PlanAggregationFunction,
distinct: bool, distinct: bool,
) -> Box<dyn Accumulator<S::StrId> + 'static> { ) -> Box<dyn Accumulator + 'static> {
match function { match function {
PlanAggregationFunction::Count => { PlanAggregationFunction::Count => {
if distinct { if distinct {
@ -581,10 +569,10 @@ where
fn eval_path_from( fn eval_path_from(
&self, &self,
path: &PlanPropertyPath<S::StrId>, path: &PlanPropertyPath,
start: EncodedTerm<S::StrId>, start: EncodedTerm,
graph_name: EncodedTerm<S::StrId>, graph_name: EncodedTerm,
) -> Box<dyn Iterator<Item = Result<EncodedTerm<S::StrId>, EvaluationError>>> { ) -> Box<dyn Iterator<Item = Result<EncodedTerm, EvaluationError>>> {
match path { match path {
PlanPropertyPath::Path(p) => Box::new( PlanPropertyPath::Path(p) => Box::new(
self.dataset self.dataset
@ -644,10 +632,10 @@ where
fn eval_path_to( fn eval_path_to(
&self, &self,
path: &PlanPropertyPath<S::StrId>, path: &PlanPropertyPath,
end: EncodedTerm<S::StrId>, end: EncodedTerm,
graph_name: EncodedTerm<S::StrId>, graph_name: EncodedTerm,
) -> Box<dyn Iterator<Item = Result<EncodedTerm<S::StrId>, EvaluationError>>> { ) -> Box<dyn Iterator<Item = Result<EncodedTerm, EvaluationError>>> {
match path { match path {
PlanPropertyPath::Path(p) => Box::new( PlanPropertyPath::Path(p) => Box::new(
self.dataset self.dataset
@ -707,13 +695,9 @@ where
fn eval_open_path( fn eval_open_path(
&self, &self,
path: &PlanPropertyPath<S::StrId>, path: &PlanPropertyPath,
graph_name: EncodedTerm<S::StrId>, graph_name: EncodedTerm,
) -> Box< ) -> Box<dyn Iterator<Item = Result<(EncodedTerm, EncodedTerm), EvaluationError>>> {
dyn Iterator<
Item = Result<(EncodedTerm<S::StrId>, EncodedTerm<S::StrId>), EvaluationError>,
>,
> {
match path { match path {
PlanPropertyPath::Path(p) => Box::new( PlanPropertyPath::Path(p) => Box::new(
self.dataset self.dataset
@ -787,9 +771,8 @@ where
fn get_subject_or_object_identity_pairs( fn get_subject_or_object_identity_pairs(
&self, &self,
graph_name: EncodedTerm<S::StrId>, graph_name: EncodedTerm,
) -> impl Iterator<Item = Result<(EncodedTerm<S::StrId>, EncodedTerm<S::StrId>), EvaluationError>> ) -> impl Iterator<Item = Result<(EncodedTerm, EncodedTerm), EvaluationError>> {
{
self.dataset self.dataset
.encoded_quads_for_pattern(None, None, None, Some(graph_name)) .encoded_quads_for_pattern(None, None, None, Some(graph_name))
.flat_map_ok(|t| once(Ok(t.subject)).chain(once(Ok(t.object)))) .flat_map_ok(|t| once(Ok(t.subject)).chain(once(Ok(t.object))))
@ -799,9 +782,9 @@ where
#[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)] #[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)]
fn eval_expression( fn eval_expression(
&self, &self,
expression: &PlanExpression<S::StrId>, expression: &PlanExpression,
tuple: &EncodedTuple<S::StrId>, tuple: &EncodedTuple,
) -> Option<EncodedTerm<S::StrId>> { ) -> Option<EncodedTerm> {
match expression { match expression {
PlanExpression::Constant(t) => Some(*t), PlanExpression::Constant(t) => Some(*t),
PlanExpression::Variable(v) => tuple.get(*v), PlanExpression::Variable(v) => tuple.get(*v),
@ -1565,7 +1548,7 @@ where
} }
} }
fn to_bool(&self, term: EncodedTerm<S::StrId>) -> Option<bool> { fn to_bool(&self, term: EncodedTerm) -> Option<bool> {
match term { match term {
EncodedTerm::BooleanLiteral(value) => Some(value), EncodedTerm::BooleanLiteral(value) => Some(value),
EncodedTerm::SmallStringLiteral(value) => Some(!value.is_empty()), EncodedTerm::SmallStringLiteral(value) => Some(!value.is_empty()),
@ -1580,7 +1563,7 @@ where
} }
} }
fn to_string_id(&self, term: EncodedTerm<S::StrId>) -> Option<SmallStringOrId<S::StrId>> { fn to_string_id(&self, term: EncodedTerm) -> Option<SmallStringOrId> {
match term { match term {
EncodedTerm::DefaultGraph => None, EncodedTerm::DefaultGraph => None,
EncodedTerm::NamedNode { iri_id } => Some(iri_id.into()), EncodedTerm::NamedNode { iri_id } => Some(iri_id.into()),
@ -1618,7 +1601,7 @@ where
} }
} }
fn to_simple_string(&self, term: EncodedTerm<S::StrId>) -> Option<String> { fn to_simple_string(&self, term: EncodedTerm) -> Option<String> {
match term { match term {
EncodedTerm::SmallStringLiteral(value) => Some(value.into()), EncodedTerm::SmallStringLiteral(value) => Some(value.into()),
EncodedTerm::BigStringLiteral { value_id } => self.dataset.get_str(value_id).ok()?, EncodedTerm::BigStringLiteral { value_id } => self.dataset.get_str(value_id).ok()?,
@ -1626,10 +1609,7 @@ where
} }
} }
fn to_simple_string_id( fn to_simple_string_id(&self, term: EncodedTerm) -> Option<SmallStringOrId> {
&self,
term: EncodedTerm<S::StrId>,
) -> Option<SmallStringOrId<S::StrId>> {
match term { match term {
EncodedTerm::SmallStringLiteral(value) => Some(value.into()), EncodedTerm::SmallStringLiteral(value) => Some(value.into()),
EncodedTerm::BigStringLiteral { value_id } => Some(value_id.into()), EncodedTerm::BigStringLiteral { value_id } => Some(value_id.into()),
@ -1637,7 +1617,7 @@ where
} }
} }
fn to_string(&self, term: EncodedTerm<S::StrId>) -> Option<String> { fn to_string(&self, term: EncodedTerm) -> Option<String> {
match term { match term {
EncodedTerm::SmallStringLiteral(value) EncodedTerm::SmallStringLiteral(value)
| EncodedTerm::SmallSmallLangStringLiteral { value, .. } | EncodedTerm::SmallSmallLangStringLiteral { value, .. }
@ -1653,8 +1633,8 @@ where
fn to_string_and_language( fn to_string_and_language(
&self, &self,
term: EncodedTerm<S::StrId>, term: EncodedTerm,
) -> Option<(String, Option<SmallStringOrId<S::StrId>>)> { ) -> Option<(String, Option<SmallStringOrId>)> {
match term { match term {
EncodedTerm::SmallStringLiteral(value) => Some((value.into(), None)), EncodedTerm::SmallStringLiteral(value) => Some((value.into(), None)),
EncodedTerm::BigStringLiteral { value_id } => { EncodedTerm::BigStringLiteral { value_id } => {
@ -1680,17 +1660,17 @@ where
} }
} }
fn build_named_node(&self, iri: &str) -> Option<EncodedTerm<S::StrId>> { fn build_named_node(&self, iri: &str) -> Option<EncodedTerm> {
Some(EncodedTerm::NamedNode { Some(EncodedTerm::NamedNode {
iri_id: self.dataset.as_ref().encode_str(iri).ok()?, iri_id: self.dataset.as_ref().encode_str(iri).ok()?,
}) })
} }
fn build_string_literal(&self, value: &str) -> Option<EncodedTerm<S::StrId>> { fn build_string_literal(&self, value: &str) -> Option<EncodedTerm> {
Some(self.build_string_literal_from_id(self.build_string_id(value)?)) Some(self.build_string_literal_from_id(self.build_string_id(value)?))
} }
fn build_string_literal_from_id(&self, id: SmallStringOrId<S::StrId>) -> EncodedTerm<S::StrId> { fn build_string_literal_from_id(&self, id: SmallStringOrId) -> EncodedTerm {
match id { match id {
SmallStringOrId::Small(value) => EncodedTerm::SmallStringLiteral(value), SmallStringOrId::Small(value) => EncodedTerm::SmallStringLiteral(value),
SmallStringOrId::Big(value_id) => EncodedTerm::BigStringLiteral { value_id }, SmallStringOrId::Big(value_id) => EncodedTerm::BigStringLiteral { value_id },
@ -1700,16 +1680,16 @@ where
fn build_lang_string_literal( fn build_lang_string_literal(
&self, &self,
value: &str, value: &str,
language_id: SmallStringOrId<S::StrId>, language_id: SmallStringOrId,
) -> Option<EncodedTerm<S::StrId>> { ) -> Option<EncodedTerm> {
Some(self.build_lang_string_literal_from_id(self.build_string_id(value)?, language_id)) Some(self.build_lang_string_literal_from_id(self.build_string_id(value)?, language_id))
} }
fn build_lang_string_literal_from_id( fn build_lang_string_literal_from_id(
&self, &self,
value_id: SmallStringOrId<S::StrId>, value_id: SmallStringOrId,
language_id: SmallStringOrId<S::StrId>, language_id: SmallStringOrId,
) -> EncodedTerm<S::StrId> { ) -> EncodedTerm {
match (value_id, language_id) { match (value_id, language_id) {
(SmallStringOrId::Small(value), SmallStringOrId::Small(language)) => { (SmallStringOrId::Small(value), SmallStringOrId::Small(language)) => {
EncodedTerm::SmallSmallLangStringLiteral { value, language } EncodedTerm::SmallSmallLangStringLiteral { value, language }
@ -1732,8 +1712,8 @@ where
fn build_plain_literal( fn build_plain_literal(
&self, &self,
value: &str, value: &str,
language: Option<SmallStringOrId<S::StrId>>, language: Option<SmallStringOrId>,
) -> Option<EncodedTerm<S::StrId>> { ) -> Option<EncodedTerm> {
if let Some(language_id) = language { if let Some(language_id) = language {
self.build_lang_string_literal(value, language_id) self.build_lang_string_literal(value, language_id)
} else { } else {
@ -1741,7 +1721,7 @@ where
} }
} }
fn build_string_id(&self, value: &str) -> Option<SmallStringOrId<S::StrId>> { fn build_string_id(&self, value: &str) -> Option<SmallStringOrId> {
Some(if let Ok(value) = SmallString::try_from(value) { Some(if let Ok(value) = SmallString::try_from(value) {
value.into() value.into()
} else { } else {
@ -1749,7 +1729,7 @@ where
}) })
} }
fn build_language_id(&self, value: EncodedTerm<S::StrId>) -> Option<SmallStringOrId<S::StrId>> { fn build_language_id(&self, value: EncodedTerm) -> Option<SmallStringOrId> {
let mut language = self.to_simple_string(value)?; let mut language = self.to_simple_string(value)?;
language.make_ascii_lowercase(); language.make_ascii_lowercase();
self.build_string_id(LanguageTag::parse(language).ok()?.as_str()) self.build_string_id(LanguageTag::parse(language).ok()?.as_str())
@ -1757,9 +1737,9 @@ where
fn to_argument_compatible_strings( fn to_argument_compatible_strings(
&self, &self,
arg1: EncodedTerm<S::StrId>, arg1: EncodedTerm,
arg2: EncodedTerm<S::StrId>, arg2: EncodedTerm,
) -> Option<(String, String, Option<SmallStringOrId<S::StrId>>)> { ) -> Option<(String, String, Option<SmallStringOrId>)> {
let (value1, language1) = self.to_string_and_language(arg1)?; let (value1, language1) = self.to_string_and_language(arg1)?;
let (value2, language2) = self.to_string_and_language(arg2)?; let (value2, language2) = self.to_string_and_language(arg2)?;
if language2.is_none() || language1 == language2 { if language2.is_none() || language1 == language2 {
@ -1769,11 +1749,7 @@ where
} }
} }
fn compile_pattern( fn compile_pattern(&self, pattern: EncodedTerm, flags: Option<EncodedTerm>) -> Option<Regex> {
&self,
pattern: EncodedTerm<S::StrId>,
flags: Option<EncodedTerm<S::StrId>>,
) -> Option<Regex> {
// TODO Avoid to compile the regex each time // TODO Avoid to compile the regex each time
let pattern = self.to_simple_string(pattern)?; let pattern = self.to_simple_string(pattern)?;
let mut regex_builder = RegexBuilder::new(&pattern); let mut regex_builder = RegexBuilder::new(&pattern);
@ -1804,9 +1780,9 @@ where
fn parse_numeric_operands( fn parse_numeric_operands(
&self, &self,
e1: &PlanExpression<S::StrId>, e1: &PlanExpression,
e2: &PlanExpression<S::StrId>, e2: &PlanExpression,
tuple: &EncodedTuple<S::StrId>, tuple: &EncodedTuple,
) -> Option<NumericBinaryOperands> { ) -> Option<NumericBinaryOperands> {
NumericBinaryOperands::new( NumericBinaryOperands::new(
self.eval_expression(e1, tuple)?, self.eval_expression(e1, tuple)?,
@ -1816,7 +1792,7 @@ where
fn decode_bindings( fn decode_bindings(
&self, &self,
iter: EncodedTuplesIterator<S::StrId>, iter: EncodedTuplesIterator,
variables: Rc<Vec<Variable>>, variables: Rc<Vec<Variable>>,
) -> QuerySolutionIter { ) -> QuerySolutionIter {
let eval = self.clone(); let eval = self.clone();
@ -1840,7 +1816,7 @@ where
&self, &self,
variables: Rc<Vec<Variable>>, variables: Rc<Vec<Variable>>,
iter: QuerySolutionIter, iter: QuerySolutionIter,
) -> EncodedTuplesIterator<S::StrId> { ) -> EncodedTuplesIterator {
let eval = self.clone(); let eval = self.clone();
Box::new(iter.map(move |solution| { Box::new(iter.map(move |solution| {
let mut encoder = eval.dataset.as_ref(); let mut encoder = eval.dataset.as_ref();
@ -1862,7 +1838,7 @@ where
clippy::cast_possible_truncation, clippy::cast_possible_truncation,
clippy::cast_precision_loss clippy::cast_precision_loss
)] )]
fn equals(&self, a: EncodedTerm<S::StrId>, b: EncodedTerm<S::StrId>) -> Option<bool> { fn equals(&self, a: EncodedTerm, b: EncodedTerm) -> Option<bool> {
match a { match a {
EncodedTerm::DefaultGraph EncodedTerm::DefaultGraph
| EncodedTerm::NamedNode { .. } | EncodedTerm::NamedNode { .. }
@ -2012,9 +1988,9 @@ where
fn cmp_according_to_expression( fn cmp_according_to_expression(
&self, &self,
tuple_a: &EncodedTuple<S::StrId>, tuple_a: &EncodedTuple,
tuple_b: &EncodedTuple<S::StrId>, tuple_b: &EncodedTuple,
expression: &PlanExpression<S::StrId>, expression: &PlanExpression,
) -> Ordering { ) -> Ordering {
self.cmp_terms( self.cmp_terms(
self.eval_expression(expression, tuple_a), self.eval_expression(expression, tuple_a),
@ -2022,11 +1998,7 @@ where
) )
} }
fn cmp_terms( fn cmp_terms(&self, a: Option<EncodedTerm>, b: Option<EncodedTerm>) -> Ordering {
&self,
a: Option<EncodedTerm<S::StrId>>,
b: Option<EncodedTerm<S::StrId>>,
) -> Ordering {
match (a, b) { match (a, b) {
(Some(a), Some(b)) => match a { (Some(a), Some(b)) => match a {
_ if a.is_blank_node() => match b { _ if a.is_blank_node() => match b {
@ -2052,11 +2024,7 @@ where
} }
#[allow(clippy::cast_precision_loss)] #[allow(clippy::cast_precision_loss)]
fn partial_cmp_literals( fn partial_cmp_literals(&self, a: EncodedTerm, b: EncodedTerm) -> Option<Ordering> {
&self,
a: EncodedTerm<S::StrId>,
b: EncodedTerm<S::StrId>,
) -> Option<Ordering> {
match a { match a {
EncodedTerm::SmallStringLiteral(a) => match b { EncodedTerm::SmallStringLiteral(a) => match b {
EncodedTerm::SmallStringLiteral(b) => a.partial_cmp(&b), EncodedTerm::SmallStringLiteral(b) => a.partial_cmp(&b),
@ -2174,7 +2142,7 @@ where
} }
} }
fn compare_str_ids(&self, a: S::StrId, b: S::StrId) -> Option<Ordering> { fn compare_str_ids(&self, a: StrHash, b: StrHash) -> Option<Ordering> {
Some( Some(
self.dataset self.dataset
.get_str(a) .get_str(a)
@ -2183,25 +2151,21 @@ where
) )
} }
fn compare_str_id_str(&self, a: S::StrId, b: &str) -> Option<Ordering> { fn compare_str_id_str(&self, a: StrHash, b: &str) -> Option<Ordering> {
Some(self.dataset.get_str(a).ok()??.as_str().cmp(b)) Some(self.dataset.get_str(a).ok()??.as_str().cmp(b))
} }
fn compare_str_str_id(&self, a: &str, b: S::StrId) -> Option<Ordering> { fn compare_str_str_id(&self, a: &str, b: StrHash) -> Option<Ordering> {
Some(a.cmp(self.dataset.get_str(b).ok()??.as_str())) Some(a.cmp(self.dataset.get_str(b).ok()??.as_str()))
} }
fn hash<H: Digest>( fn hash<H: Digest>(&self, arg: &PlanExpression, tuple: &EncodedTuple) -> Option<EncodedTerm> {
&self,
arg: &PlanExpression<S::StrId>,
tuple: &EncodedTuple<S::StrId>,
) -> Option<EncodedTerm<S::StrId>> {
let input = self.to_simple_string(self.eval_expression(arg, tuple)?)?; let input = self.to_simple_string(self.eval_expression(arg, tuple)?)?;
let hash = hex::encode(H::new().chain(input.as_str()).finalize()); let hash = hex::encode(H::new().chain(input.as_str()).finalize());
self.build_string_literal(&hash) self.build_string_literal(&hash)
} }
fn datatype(&self, value: EncodedTerm<S::StrId>) -> Option<EncodedTerm<S::StrId>> { fn datatype(&self, value: EncodedTerm) -> Option<EncodedTerm> {
//TODO: optimize? //TODO: optimize?
match value { match value {
EncodedTerm::NamedNode { .. } EncodedTerm::NamedNode { .. }
@ -2269,7 +2233,7 @@ enum NumericBinaryOperands {
impl NumericBinaryOperands { impl NumericBinaryOperands {
#[allow(clippy::cast_precision_loss)] #[allow(clippy::cast_precision_loss)]
fn new<I: StrId>(a: EncodedTerm<I>, b: EncodedTerm<I>) -> Option<Self> { fn new(a: EncodedTerm, b: EncodedTerm) -> Option<Self> {
match (a, b) { match (a, b) {
(EncodedTerm::FloatLiteral(v1), EncodedTerm::FloatLiteral(v2)) => { (EncodedTerm::FloatLiteral(v1), EncodedTerm::FloatLiteral(v2)) => {
Some(NumericBinaryOperands::Float(v1, v2)) Some(NumericBinaryOperands::Float(v1, v2))
@ -2387,32 +2351,25 @@ impl NumericBinaryOperands {
} }
} }
fn get_pattern_value<I: StrId>( fn get_pattern_value(selector: &PatternValue, tuple: &EncodedTuple) -> Option<EncodedTerm> {
selector: &PatternValue<I>,
tuple: &EncodedTuple<I>,
) -> Option<EncodedTerm<I>> {
match selector { match selector {
PatternValue::Constant(term) => Some(*term), PatternValue::Constant(term) => Some(*term),
PatternValue::Variable(v) => tuple.get(*v), PatternValue::Variable(v) => tuple.get(*v),
} }
} }
fn put_pattern_value<I: StrId>( fn put_pattern_value(selector: &PatternValue, value: EncodedTerm, tuple: &mut EncodedTuple) {
selector: &PatternValue<I>,
value: EncodedTerm<I>,
tuple: &mut EncodedTuple<I>,
) {
match selector { match selector {
PatternValue::Constant(_) => (), PatternValue::Constant(_) => (),
PatternValue::Variable(v) => tuple.set(*v, value), PatternValue::Variable(v) => tuple.set(*v, value),
} }
} }
fn put_variable_value<I: StrId>( fn put_variable_value(
selector: &Variable, selector: &Variable,
variables: &[Variable], variables: &[Variable],
value: EncodedTerm<I>, value: EncodedTerm,
tuple: &mut EncodedTuple<I>, tuple: &mut EncodedTuple,
) { ) {
for (i, v) in variables.iter().enumerate() { for (i, v) in variables.iter().enumerate() {
if selector == v { if selector == v {
@ -2422,17 +2379,13 @@ fn put_variable_value<I: StrId>(
} }
} }
fn unbind_variables<I: StrId>(binding: &mut EncodedTuple<I>, variables: &[usize]) { fn unbind_variables(binding: &mut EncodedTuple, variables: &[usize]) {
for var in variables { for var in variables {
binding.unset(*var) binding.unset(*var)
} }
} }
fn combine_tuples<I: StrId>( fn combine_tuples(mut a: EncodedTuple, b: &EncodedTuple, vars: &[usize]) -> Option<EncodedTuple> {
mut a: EncodedTuple<I>,
b: &EncodedTuple<I>,
vars: &[usize],
) -> Option<EncodedTuple<I>> {
for var in vars { for var in vars {
if let Some(b_value) = b.get(*var) { if let Some(b_value) = b.get(*var) {
if let Some(a_value) = a.get(*var) { if let Some(a_value) = a.get(*var) {
@ -2447,10 +2400,7 @@ fn combine_tuples<I: StrId>(
Some(a) Some(a)
} }
pub fn are_compatible_and_not_disjointed<I: StrId>( pub fn are_compatible_and_not_disjointed(a: &EncodedTuple, b: &EncodedTuple) -> bool {
a: &EncodedTuple<I>,
b: &EncodedTuple<I>,
) -> bool {
let mut found_intersection = false; let mut found_intersection = false;
for (a_value, b_value) in a.iter().zip(b.iter()) { for (a_value, b_value) in a.iter().zip(b.iter()) {
if let (Some(a_value), Some(b_value)) = (a_value, b_value) { if let (Some(a_value), Some(b_value)) = (a_value, b_value) {
@ -2463,16 +2413,16 @@ pub fn are_compatible_and_not_disjointed<I: StrId>(
found_intersection found_intersection
} }
struct JoinIterator<I: StrId> { struct JoinIterator {
left: Vec<EncodedTuple<I>>, left: Vec<EncodedTuple>,
right_iter: EncodedTuplesIterator<I>, right_iter: EncodedTuplesIterator,
buffered_results: Vec<Result<EncodedTuple<I>, EvaluationError>>, buffered_results: Vec<Result<EncodedTuple, EvaluationError>>,
} }
impl<I: StrId> Iterator for JoinIterator<I> { impl Iterator for JoinIterator {
type Item = Result<EncodedTuple<I>, EvaluationError>; type Item = Result<EncodedTuple, EvaluationError>;
fn next(&mut self) -> Option<Result<EncodedTuple<I>, EvaluationError>> { fn next(&mut self) -> Option<Result<EncodedTuple, EvaluationError>> {
loop { loop {
if let Some(result) = self.buffered_results.pop() { if let Some(result) = self.buffered_results.pop() {
return Some(result); return Some(result);
@ -2490,15 +2440,15 @@ impl<I: StrId> Iterator for JoinIterator<I> {
} }
} }
struct AntiJoinIterator<I: StrId> { struct AntiJoinIterator {
left_iter: EncodedTuplesIterator<I>, left_iter: EncodedTuplesIterator,
right: Vec<EncodedTuple<I>>, right: Vec<EncodedTuple>,
} }
impl<I: StrId> Iterator for AntiJoinIterator<I> { impl Iterator for AntiJoinIterator {
type Item = Result<EncodedTuple<I>, EvaluationError>; type Item = Result<EncodedTuple, EvaluationError>;
fn next(&mut self) -> Option<Result<EncodedTuple<I>, EvaluationError>> { fn next(&mut self) -> Option<Result<EncodedTuple, EvaluationError>> {
loop { loop {
match self.left_iter.next()? { match self.left_iter.next()? {
Ok(left_tuple) => { Ok(left_tuple) => {
@ -2517,18 +2467,18 @@ impl<I: StrId> Iterator for AntiJoinIterator<I> {
struct LeftJoinIterator<S: ReadableEncodedStore + 'static> { struct LeftJoinIterator<S: ReadableEncodedStore + 'static> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
right_plan: Rc<PlanNode<S::StrId>>, right_plan: Rc<PlanNode>,
left_iter: EncodedTuplesIterator<S::StrId>, left_iter: EncodedTuplesIterator,
current_right: EncodedTuplesIterator<S::StrId>, current_right: EncodedTuplesIterator,
} }
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for LeftJoinIterator<S> impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for LeftJoinIterator<S>
where where
for<'a> &'a S: StrContainer<StrId = S::StrId>, for<'a> &'a S: StrContainer,
{ {
type Item = Result<EncodedTuple<S::StrId>, EvaluationError>; type Item = Result<EncodedTuple, EvaluationError>;
fn next(&mut self) -> Option<Result<EncodedTuple<S::StrId>, EvaluationError>> { fn next(&mut self) -> Option<Result<EncodedTuple, EvaluationError>> {
if let Some(tuple) = self.current_right.next() { if let Some(tuple) = self.current_right.next() {
return Some(tuple); return Some(tuple);
} }
@ -2548,20 +2498,20 @@ where
struct BadLeftJoinIterator<S: ReadableEncodedStore + 'static> { struct BadLeftJoinIterator<S: ReadableEncodedStore + 'static> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
right_plan: Rc<PlanNode<S::StrId>>, right_plan: Rc<PlanNode>,
left_iter: EncodedTuplesIterator<S::StrId>, left_iter: EncodedTuplesIterator,
current_left: Option<EncodedTuple<S::StrId>>, current_left: Option<EncodedTuple>,
current_right: EncodedTuplesIterator<S::StrId>, current_right: EncodedTuplesIterator,
problem_vars: Rc<Vec<usize>>, problem_vars: Rc<Vec<usize>>,
} }
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for BadLeftJoinIterator<S> impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for BadLeftJoinIterator<S>
where where
for<'a> &'a S: StrContainer<StrId = S::StrId>, for<'a> &'a S: StrContainer,
{ {
type Item = Result<EncodedTuple<S::StrId>, EvaluationError>; type Item = Result<EncodedTuple, EvaluationError>;
fn next(&mut self) -> Option<Result<EncodedTuple<S::StrId>, EvaluationError>> { fn next(&mut self) -> Option<Result<EncodedTuple, EvaluationError>> {
while let Some(right_tuple) = self.current_right.next() { while let Some(right_tuple) = self.current_right.next() {
match right_tuple { match right_tuple {
Ok(right_tuple) => { Ok(right_tuple) => {
@ -2603,19 +2553,19 @@ where
struct UnionIterator<S: ReadableEncodedStore + 'static> { struct UnionIterator<S: ReadableEncodedStore + 'static> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
plans: Vec<Rc<PlanNode<S::StrId>>>, plans: Vec<Rc<PlanNode>>,
input: EncodedTuple<S::StrId>, input: EncodedTuple,
current_iterator: EncodedTuplesIterator<S::StrId>, current_iterator: EncodedTuplesIterator,
current_plan: usize, current_plan: usize,
} }
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for UnionIterator<S> impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for UnionIterator<S>
where where
for<'a> &'a S: StrContainer<StrId = S::StrId>, for<'a> &'a S: StrContainer,
{ {
type Item = Result<EncodedTuple<S::StrId>, EvaluationError>; type Item = Result<EncodedTuple, EvaluationError>;
fn next(&mut self) -> Option<Result<EncodedTuple<S::StrId>, EvaluationError>> { fn next(&mut self) -> Option<Result<EncodedTuple, EvaluationError>> {
loop { loop {
if let Some(tuple) = self.current_iterator.next() { if let Some(tuple) = self.current_iterator.next() {
return Some(tuple); return Some(tuple);
@ -2633,10 +2583,10 @@ where
struct ConstructIterator<S: ReadableEncodedStore + 'static> { struct ConstructIterator<S: ReadableEncodedStore + 'static> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
iter: EncodedTuplesIterator<S::StrId>, iter: EncodedTuplesIterator,
template: Vec<TripleTemplate<S::StrId>>, template: Vec<TripleTemplate>,
buffered_results: Vec<Result<Triple, EvaluationError>>, buffered_results: Vec<Result<Triple, EvaluationError>>,
bnodes: Vec<EncodedTerm<S::StrId>>, bnodes: Vec<EncodedTerm>,
} }
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for ConstructIterator<S> { impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for ConstructIterator<S> {
@ -2672,11 +2622,11 @@ impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for Co
} }
} }
fn get_triple_template_value<I: StrId>( fn get_triple_template_value(
selector: &TripleTemplateValue<I>, selector: &TripleTemplateValue,
tuple: &EncodedTuple<I>, tuple: &EncodedTuple,
bnodes: &mut Vec<EncodedTerm<I>>, bnodes: &mut Vec<EncodedTerm>,
) -> Option<EncodedTerm<I>> { ) -> Option<EncodedTerm> {
match selector { match selector {
TripleTemplateValue::Constant(term) => Some(*term), TripleTemplateValue::Constant(term) => Some(*term),
TripleTemplateValue::Variable(v) => tuple.get(*v), TripleTemplateValue::Variable(v) => tuple.get(*v),
@ -2689,15 +2639,15 @@ fn get_triple_template_value<I: StrId>(
} }
} }
fn new_bnode<I: StrId>() -> EncodedTerm<I> { fn new_bnode() -> EncodedTerm {
EncodedTerm::NumericalBlankNode { id: random() } EncodedTerm::NumericalBlankNode { id: random() }
} }
fn decode_triple<D: Decoder>( fn decode_triple<D: Decoder>(
decoder: &D, decoder: &D,
subject: EncodedTerm<D::StrId>, subject: EncodedTerm,
predicate: EncodedTerm<D::StrId>, predicate: EncodedTerm,
object: EncodedTerm<D::StrId>, object: EncodedTerm,
) -> Result<Triple, EvaluationError> { ) -> Result<Triple, EvaluationError> {
Ok(Triple::new( Ok(Triple::new(
decoder.decode_named_or_blank_node(subject)?, decoder.decode_named_or_blank_node(subject)?,
@ -2708,8 +2658,8 @@ fn decode_triple<D: Decoder>(
struct DescribeIterator<S: ReadableEncodedStore + 'static> { struct DescribeIterator<S: ReadableEncodedStore + 'static> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
iter: EncodedTuplesIterator<S::StrId>, iter: EncodedTuplesIterator,
quads: Box<dyn Iterator<Item = Result<EncodedQuad<S::StrId>, EvaluationError>>>, quads: Box<dyn Iterator<Item = Result<EncodedQuad, EvaluationError>>>,
} }
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for DescribeIterator<S> { impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Iterator for DescribeIterator<S> {
@ -2894,19 +2844,19 @@ impl<
} }
} }
trait Accumulator<I: StrId> { trait Accumulator {
fn add(&mut self, element: Option<EncodedTerm<I>>); fn add(&mut self, element: Option<EncodedTerm>);
fn state(&self) -> Option<EncodedTerm<I>>; fn state(&self) -> Option<EncodedTerm>;
} }
#[derive(Default, Debug)] #[derive(Default, Debug)]
struct DistinctAccumulator<I: StrId, T: Accumulator<I>> { struct DistinctAccumulator<T: Accumulator> {
seen: HashSet<Option<EncodedTerm<I>>>, seen: HashSet<Option<EncodedTerm>>,
inner: T, inner: T,
} }
impl<I: StrId, T: Accumulator<I>> DistinctAccumulator<I, T> { impl<T: Accumulator> DistinctAccumulator<T> {
fn new(inner: T) -> Self { fn new(inner: T) -> Self {
Self { Self {
seen: HashSet::default(), seen: HashSet::default(),
@ -2915,14 +2865,14 @@ impl<I: StrId, T: Accumulator<I>> DistinctAccumulator<I, T> {
} }
} }
impl<I: StrId, T: Accumulator<I>> Accumulator<I> for DistinctAccumulator<I, T> { impl<T: Accumulator> Accumulator for DistinctAccumulator<T> {
fn add(&mut self, element: Option<EncodedTerm<I>>) { fn add(&mut self, element: Option<EncodedTerm>) {
if self.seen.insert(element) { if self.seen.insert(element) {
self.inner.add(element) self.inner.add(element)
} }
} }
fn state(&self) -> Option<EncodedTerm<I>> { fn state(&self) -> Option<EncodedTerm> {
self.inner.state() self.inner.state()
} }
} }
@ -2932,22 +2882,22 @@ struct CountAccumulator {
count: i64, count: i64,
} }
impl<I: StrId> Accumulator<I> for CountAccumulator { impl Accumulator for CountAccumulator {
fn add(&mut self, _element: Option<EncodedTerm<I>>) { fn add(&mut self, _element: Option<EncodedTerm>) {
self.count += 1; self.count += 1;
} }
fn state(&self) -> Option<EncodedTerm<I>> { fn state(&self) -> Option<EncodedTerm> {
Some(self.count.into()) Some(self.count.into())
} }
} }
#[derive(Debug)] #[derive(Debug)]
struct SumAccumulator<I: StrId> { struct SumAccumulator {
sum: Option<EncodedTerm<I>>, sum: Option<EncodedTerm>,
} }
impl<I: StrId> Default for SumAccumulator<I> { impl Default for SumAccumulator {
fn default() -> Self { fn default() -> Self {
Self { Self {
sum: Some(0.into()), sum: Some(0.into()),
@ -2955,8 +2905,8 @@ impl<I: StrId> Default for SumAccumulator<I> {
} }
} }
impl<I: StrId> Accumulator<I> for SumAccumulator<I> { impl Accumulator for SumAccumulator {
fn add(&mut self, element: Option<EncodedTerm<I>>) { fn add(&mut self, element: Option<EncodedTerm>) {
if let Some(sum) = self.sum { if let Some(sum) = self.sum {
if let Some(operands) = element.and_then(|e| NumericBinaryOperands::new(sum, e)) { if let Some(operands) = element.and_then(|e| NumericBinaryOperands::new(sum, e)) {
//TODO: unify with addition? //TODO: unify with addition?
@ -2974,18 +2924,18 @@ impl<I: StrId> Accumulator<I> for SumAccumulator<I> {
} }
} }
fn state(&self) -> Option<EncodedTerm<I>> { fn state(&self) -> Option<EncodedTerm> {
self.sum self.sum
} }
} }
#[derive(Debug)] #[derive(Debug)]
struct AvgAccumulator<I: StrId> { struct AvgAccumulator {
sum: SumAccumulator<I>, sum: SumAccumulator,
count: CountAccumulator, count: CountAccumulator,
} }
impl<I: StrId> Default for AvgAccumulator<I> { impl Default for AvgAccumulator {
fn default() -> Self { fn default() -> Self {
Self { Self {
sum: SumAccumulator::default(), sum: SumAccumulator::default(),
@ -2994,13 +2944,13 @@ impl<I: StrId> Default for AvgAccumulator<I> {
} }
} }
impl<I: StrId> Accumulator<I> for AvgAccumulator<I> { impl Accumulator for AvgAccumulator {
fn add(&mut self, element: Option<EncodedTerm<I>>) { fn add(&mut self, element: Option<EncodedTerm>) {
self.sum.add(element); self.sum.add(element);
self.count.add(element); self.count.add(element);
} }
fn state(&self) -> Option<EncodedTerm<I>> { fn state(&self) -> Option<EncodedTerm> {
let sum = self.sum.state()?; let sum = self.sum.state()?;
let count = self.count.state()?; let count = self.count.state()?;
if count == EncodedTerm::from(0) { if count == EncodedTerm::from(0) {
@ -3024,7 +2974,7 @@ impl<I: StrId> Accumulator<I> for AvgAccumulator<I> {
#[allow(clippy::option_option)] #[allow(clippy::option_option)]
struct MinAccumulator<S: ReadableEncodedStore + 'static> { struct MinAccumulator<S: ReadableEncodedStore + 'static> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
min: Option<Option<EncodedTerm<S::StrId>>>, min: Option<Option<EncodedTerm>>,
} }
impl<S: ReadableEncodedStore + 'static> MinAccumulator<S> { impl<S: ReadableEncodedStore + 'static> MinAccumulator<S> {
@ -3033,12 +2983,11 @@ impl<S: ReadableEncodedStore + 'static> MinAccumulator<S> {
} }
} }
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Accumulator<S::StrId> impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Accumulator for MinAccumulator<S>
for MinAccumulator<S>
where where
for<'a> &'a S: StrContainer<StrId = S::StrId>, for<'a> &'a S: StrContainer,
{ {
fn add(&mut self, element: Option<EncodedTerm<S::StrId>>) { fn add(&mut self, element: Option<EncodedTerm>) {
if let Some(min) = self.min { if let Some(min) = self.min {
if self.eval.cmp_terms(element, min) == Ordering::Less { if self.eval.cmp_terms(element, min) == Ordering::Less {
self.min = Some(element) self.min = Some(element)
@ -3048,7 +2997,7 @@ where
} }
} }
fn state(&self) -> Option<EncodedTerm<S::StrId>> { fn state(&self) -> Option<EncodedTerm> {
self.min.and_then(|v| v) self.min.and_then(|v| v)
} }
} }
@ -3056,7 +3005,7 @@ where
#[allow(clippy::option_option)] #[allow(clippy::option_option)]
struct MaxAccumulator<S: ReadableEncodedStore + 'static> { struct MaxAccumulator<S: ReadableEncodedStore + 'static> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
max: Option<Option<EncodedTerm<S::StrId>>>, max: Option<Option<EncodedTerm>>,
} }
impl<S: ReadableEncodedStore + 'static> MaxAccumulator<S> { impl<S: ReadableEncodedStore + 'static> MaxAccumulator<S> {
@ -3065,12 +3014,11 @@ impl<S: ReadableEncodedStore + 'static> MaxAccumulator<S> {
} }
} }
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Accumulator<S::StrId> impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Accumulator for MaxAccumulator<S>
for MaxAccumulator<S>
where where
for<'a> &'a S: StrContainer<StrId = S::StrId>, for<'a> &'a S: StrContainer,
{ {
fn add(&mut self, element: Option<EncodedTerm<S::StrId>>) { fn add(&mut self, element: Option<EncodedTerm>) {
if let Some(max) = self.max { if let Some(max) = self.max {
if self.eval.cmp_terms(element, max) == Ordering::Greater { if self.eval.cmp_terms(element, max) == Ordering::Greater {
self.max = Some(element) self.max = Some(element)
@ -3080,30 +3028,30 @@ where
} }
} }
fn state(&self) -> Option<EncodedTerm<S::StrId>> { fn state(&self) -> Option<EncodedTerm> {
self.max.and_then(|v| v) self.max.and_then(|v| v)
} }
} }
#[derive(Debug)] #[derive(Debug)]
struct SampleAccumulator<I: StrId> { struct SampleAccumulator {
value: Option<EncodedTerm<I>>, value: Option<EncodedTerm>,
} }
impl<I: StrId> Default for SampleAccumulator<I> { impl Default for SampleAccumulator {
fn default() -> Self { fn default() -> Self {
Self { value: None } Self { value: None }
} }
} }
impl<I: StrId> Accumulator<I> for SampleAccumulator<I> { impl Accumulator for SampleAccumulator {
fn add(&mut self, element: Option<EncodedTerm<I>>) { fn add(&mut self, element: Option<EncodedTerm>) {
if element.is_some() { if element.is_some() {
self.value = element self.value = element
} }
} }
fn state(&self) -> Option<EncodedTerm<I>> { fn state(&self) -> Option<EncodedTerm> {
self.value self.value
} }
} }
@ -3112,7 +3060,7 @@ impl<I: StrId> Accumulator<I> for SampleAccumulator<I> {
struct GroupConcatAccumulator<S: ReadableEncodedStore + 'static> { struct GroupConcatAccumulator<S: ReadableEncodedStore + 'static> {
eval: SimpleEvaluator<S>, eval: SimpleEvaluator<S>,
concat: Option<String>, concat: Option<String>,
language: Option<Option<SmallStringOrId<S::StrId>>>, language: Option<Option<SmallStringOrId>>,
separator: Rc<String>, separator: Rc<String>,
} }
@ -3127,12 +3075,12 @@ impl<S: ReadableEncodedStore + 'static> GroupConcatAccumulator<S> {
} }
} }
impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Accumulator<S::StrId> impl<S: ReadableEncodedStore<Error = EvaluationError> + 'static> Accumulator
for GroupConcatAccumulator<S> for GroupConcatAccumulator<S>
where where
for<'a> &'a S: StrContainer<StrId = S::StrId>, for<'a> &'a S: StrContainer,
{ {
fn add(&mut self, element: Option<EncodedTerm<S::StrId>>) { fn add(&mut self, element: Option<EncodedTerm>) {
if let Some(concat) = self.concat.as_mut() { if let Some(concat) = self.concat.as_mut() {
if let Some(element) = element { if let Some(element) = element {
if let Some((value, e_language)) = self.eval.to_string_and_language(element) { if let Some((value, e_language)) = self.eval.to_string_and_language(element) {
@ -3150,7 +3098,7 @@ where
} }
} }
fn state(&self) -> Option<EncodedTerm<S::StrId>> { fn state(&self) -> Option<EncodedTerm> {
self.concat.as_ref().and_then(|result| { self.concat.as_ref().and_then(|result| {
self.eval self.eval
.build_plain_literal(result, self.language.and_then(|v| v)) .build_plain_literal(result, self.language.and_then(|v| v))
@ -3192,19 +3140,19 @@ fn write_hexa_bytes(bytes: &[u8], buffer: &mut String) {
} }
#[derive(Eq, PartialEq, Clone, Copy)] #[derive(Eq, PartialEq, Clone, Copy)]
enum SmallStringOrId<I: StrId> { enum SmallStringOrId {
Small(SmallString), Small(SmallString),
Big(I), Big(StrHash),
} }
impl<I: StrId> From<SmallString> for SmallStringOrId<I> { impl From<SmallString> for SmallStringOrId {
fn from(value: SmallString) -> Self { fn from(value: SmallString) -> Self {
Self::Small(value) Self::Small(value)
} }
} }
impl<I: StrId> From<I> for SmallStringOrId<I> { impl From<StrHash> for SmallStringOrId {
fn from(value: I) -> Self { fn from(value: StrHash) -> Self {
Self::Big(value) Self::Big(value)
} }
} }

@ -182,7 +182,7 @@ impl From<QueryOptions> for UpdateOptions {
pub(crate) fn evaluate_update< pub(crate) fn evaluate_update<
R: ReadableEncodedStore + Clone + 'static, R: ReadableEncodedStore + Clone + 'static,
W: StrContainer<StrId = R::StrId> + WritableEncodedStore<StrId = R::StrId>, W: StrContainer + WritableEncodedStore,
>( >(
read: R, read: R,
write: &mut W, write: &mut W,

@ -1,89 +1,89 @@
use crate::sparql::algebra::GraphPattern; use crate::sparql::algebra::GraphPattern;
use crate::sparql::model::Variable; use crate::sparql::model::Variable;
use crate::store::numeric_encoder::{EncodedTerm, StrId}; use crate::store::numeric_encoder::EncodedTerm;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::rc::Rc; use std::rc::Rc;
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum PlanNode<I: StrId> { pub enum PlanNode {
Init, Init,
StaticBindings { StaticBindings {
tuples: Vec<EncodedTuple<I>>, tuples: Vec<EncodedTuple>,
}, },
Service { Service {
service_name: PatternValue<I>, service_name: PatternValue,
variables: Rc<Vec<Variable>>, variables: Rc<Vec<Variable>>,
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
graph_pattern: Rc<GraphPattern>, graph_pattern: Rc<GraphPattern>,
silent: bool, silent: bool,
}, },
QuadPatternJoin { QuadPatternJoin {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
subject: PatternValue<I>, subject: PatternValue,
predicate: PatternValue<I>, predicate: PatternValue,
object: PatternValue<I>, object: PatternValue,
graph_name: PatternValue<I>, graph_name: PatternValue,
}, },
PathPatternJoin { PathPatternJoin {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
subject: PatternValue<I>, subject: PatternValue,
path: Rc<PlanPropertyPath<I>>, path: Rc<PlanPropertyPath>,
object: PatternValue<I>, object: PatternValue,
graph_name: PatternValue<I>, graph_name: PatternValue,
}, },
Join { Join {
left: Rc<PlanNode<I>>, left: Rc<PlanNode>,
right: Rc<PlanNode<I>>, right: Rc<PlanNode>,
}, },
AntiJoin { AntiJoin {
left: Rc<PlanNode<I>>, left: Rc<PlanNode>,
right: Rc<PlanNode<I>>, right: Rc<PlanNode>,
}, },
Filter { Filter {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
expression: Rc<PlanExpression<I>>, expression: Rc<PlanExpression>,
}, },
Union { Union {
children: Vec<Rc<PlanNode<I>>>, children: Vec<Rc<PlanNode>>,
}, },
LeftJoin { LeftJoin {
left: Rc<PlanNode<I>>, left: Rc<PlanNode>,
right: Rc<PlanNode<I>>, right: Rc<PlanNode>,
possible_problem_vars: Rc<Vec<usize>>, //Variables that should not be part of the entry of the left join possible_problem_vars: Rc<Vec<usize>>, //Variables that should not be part of the entry of the left join
}, },
Extend { Extend {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
position: usize, position: usize,
expression: Rc<PlanExpression<I>>, expression: Rc<PlanExpression>,
}, },
Sort { Sort {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
by: Vec<Comparator<I>>, by: Vec<Comparator>,
}, },
HashDeduplicate { HashDeduplicate {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
}, },
Skip { Skip {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
count: usize, count: usize,
}, },
Limit { Limit {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
count: usize, count: usize,
}, },
Project { Project {
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
mapping: Rc<Vec<(usize, usize)>>, // pairs of (variable key in child, variable key in output) mapping: Rc<Vec<(usize, usize)>>, // pairs of (variable key in child, variable key in output)
}, },
Aggregate { Aggregate {
// By definition the group by key are the range 0..key_mapping.len() // By definition the group by key are the range 0..key_mapping.len()
child: Rc<PlanNode<I>>, child: Rc<PlanNode>,
key_mapping: Rc<Vec<(usize, usize)>>, // aggregate key pairs of (variable key in child, variable key in output) key_mapping: Rc<Vec<(usize, usize)>>, // aggregate key pairs of (variable key in child, variable key in output)
aggregates: Rc<Vec<(PlanAggregation<I>, usize)>>, aggregates: Rc<Vec<(PlanAggregation, usize)>>,
}, },
} }
impl<I: StrId> PlanNode<I> { impl PlanNode {
/// Returns variables that might be bound in the result set /// Returns variables that might be bound in the result set
pub fn maybe_bound_variables(&self) -> BTreeSet<usize> { pub fn maybe_bound_variables(&self) -> BTreeSet<usize> {
let mut set = BTreeSet::default(); let mut set = BTreeSet::default();
@ -194,12 +194,12 @@ impl<I: StrId> PlanNode<I> {
} }
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum PatternValue<I: StrId> { pub enum PatternValue {
Constant(EncodedTerm<I>), Constant(EncodedTerm),
Variable(usize), Variable(usize),
} }
impl<I: StrId> PatternValue<I> { impl PatternValue {
pub fn is_var(&self) -> bool { pub fn is_var(&self) -> bool {
match self { match self {
PatternValue::Constant(_) => false, PatternValue::Constant(_) => false,
@ -209,107 +209,107 @@ impl<I: StrId> PatternValue<I> {
} }
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum PlanExpression<I: StrId> { pub enum PlanExpression {
Constant(EncodedTerm<I>), Constant(EncodedTerm),
Variable(usize), Variable(usize),
Exists(Rc<PlanNode<I>>), Exists(Rc<PlanNode>),
Or(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Or(Box<PlanExpression>, Box<PlanExpression>),
And(Box<PlanExpression<I>>, Box<PlanExpression<I>>), And(Box<PlanExpression>, Box<PlanExpression>),
Equal(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Equal(Box<PlanExpression>, Box<PlanExpression>),
Greater(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Greater(Box<PlanExpression>, Box<PlanExpression>),
GreaterOrEqual(Box<PlanExpression<I>>, Box<PlanExpression<I>>), GreaterOrEqual(Box<PlanExpression>, Box<PlanExpression>),
Less(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Less(Box<PlanExpression>, Box<PlanExpression>),
LessOrEqual(Box<PlanExpression<I>>, Box<PlanExpression<I>>), LessOrEqual(Box<PlanExpression>, Box<PlanExpression>),
In(Box<PlanExpression<I>>, Vec<PlanExpression<I>>), In(Box<PlanExpression>, Vec<PlanExpression>),
Add(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Add(Box<PlanExpression>, Box<PlanExpression>),
Subtract(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Subtract(Box<PlanExpression>, Box<PlanExpression>),
Multiply(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Multiply(Box<PlanExpression>, Box<PlanExpression>),
Divide(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Divide(Box<PlanExpression>, Box<PlanExpression>),
UnaryPlus(Box<PlanExpression<I>>), UnaryPlus(Box<PlanExpression>),
UnaryMinus(Box<PlanExpression<I>>), UnaryMinus(Box<PlanExpression>),
Not(Box<PlanExpression<I>>), Not(Box<PlanExpression>),
Str(Box<PlanExpression<I>>), Str(Box<PlanExpression>),
Lang(Box<PlanExpression<I>>), Lang(Box<PlanExpression>),
LangMatches(Box<PlanExpression<I>>, Box<PlanExpression<I>>), LangMatches(Box<PlanExpression>, Box<PlanExpression>),
Datatype(Box<PlanExpression<I>>), Datatype(Box<PlanExpression>),
Bound(usize), Bound(usize),
Iri(Box<PlanExpression<I>>), Iri(Box<PlanExpression>),
BNode(Option<Box<PlanExpression<I>>>), BNode(Option<Box<PlanExpression>>),
Rand, Rand,
Abs(Box<PlanExpression<I>>), Abs(Box<PlanExpression>),
Ceil(Box<PlanExpression<I>>), Ceil(Box<PlanExpression>),
Floor(Box<PlanExpression<I>>), Floor(Box<PlanExpression>),
Round(Box<PlanExpression<I>>), Round(Box<PlanExpression>),
Concat(Vec<PlanExpression<I>>), Concat(Vec<PlanExpression>),
SubStr( SubStr(
Box<PlanExpression<I>>, Box<PlanExpression>,
Box<PlanExpression<I>>, Box<PlanExpression>,
Option<Box<PlanExpression<I>>>, Option<Box<PlanExpression>>,
), ),
StrLen(Box<PlanExpression<I>>), StrLen(Box<PlanExpression>),
Replace( Replace(
Box<PlanExpression<I>>, Box<PlanExpression>,
Box<PlanExpression<I>>, Box<PlanExpression>,
Box<PlanExpression<I>>, Box<PlanExpression>,
Option<Box<PlanExpression<I>>>, Option<Box<PlanExpression>>,
), ),
UCase(Box<PlanExpression<I>>), UCase(Box<PlanExpression>),
LCase(Box<PlanExpression<I>>), LCase(Box<PlanExpression>),
EncodeForUri(Box<PlanExpression<I>>), EncodeForUri(Box<PlanExpression>),
Contains(Box<PlanExpression<I>>, Box<PlanExpression<I>>), Contains(Box<PlanExpression>, Box<PlanExpression>),
StrStarts(Box<PlanExpression<I>>, Box<PlanExpression<I>>), StrStarts(Box<PlanExpression>, Box<PlanExpression>),
StrEnds(Box<PlanExpression<I>>, Box<PlanExpression<I>>), StrEnds(Box<PlanExpression>, Box<PlanExpression>),
StrBefore(Box<PlanExpression<I>>, Box<PlanExpression<I>>), StrBefore(Box<PlanExpression>, Box<PlanExpression>),
StrAfter(Box<PlanExpression<I>>, Box<PlanExpression<I>>), StrAfter(Box<PlanExpression>, Box<PlanExpression>),
Year(Box<PlanExpression<I>>), Year(Box<PlanExpression>),
Month(Box<PlanExpression<I>>), Month(Box<PlanExpression>),
Day(Box<PlanExpression<I>>), Day(Box<PlanExpression>),
Hours(Box<PlanExpression<I>>), Hours(Box<PlanExpression>),
Minutes(Box<PlanExpression<I>>), Minutes(Box<PlanExpression>),
Seconds(Box<PlanExpression<I>>), Seconds(Box<PlanExpression>),
Timezone(Box<PlanExpression<I>>), Timezone(Box<PlanExpression>),
Tz(Box<PlanExpression<I>>), Tz(Box<PlanExpression>),
Now, Now,
Uuid, Uuid,
StrUuid, StrUuid,
Md5(Box<PlanExpression<I>>), Md5(Box<PlanExpression>),
Sha1(Box<PlanExpression<I>>), Sha1(Box<PlanExpression>),
Sha256(Box<PlanExpression<I>>), Sha256(Box<PlanExpression>),
Sha384(Box<PlanExpression<I>>), Sha384(Box<PlanExpression>),
Sha512(Box<PlanExpression<I>>), Sha512(Box<PlanExpression>),
Coalesce(Vec<PlanExpression<I>>), Coalesce(Vec<PlanExpression>),
If( If(
Box<PlanExpression<I>>, Box<PlanExpression>,
Box<PlanExpression<I>>, Box<PlanExpression>,
Box<PlanExpression<I>>, Box<PlanExpression>,
), ),
StrLang(Box<PlanExpression<I>>, Box<PlanExpression<I>>), StrLang(Box<PlanExpression>, Box<PlanExpression>),
StrDt(Box<PlanExpression<I>>, Box<PlanExpression<I>>), StrDt(Box<PlanExpression>, Box<PlanExpression>),
SameTerm(Box<PlanExpression<I>>, Box<PlanExpression<I>>), SameTerm(Box<PlanExpression>, Box<PlanExpression>),
IsIri(Box<PlanExpression<I>>), IsIri(Box<PlanExpression>),
IsBlank(Box<PlanExpression<I>>), IsBlank(Box<PlanExpression>),
IsLiteral(Box<PlanExpression<I>>), IsLiteral(Box<PlanExpression>),
IsNumeric(Box<PlanExpression<I>>), IsNumeric(Box<PlanExpression>),
Regex( Regex(
Box<PlanExpression<I>>, Box<PlanExpression>,
Box<PlanExpression<I>>, Box<PlanExpression>,
Option<Box<PlanExpression<I>>>, Option<Box<PlanExpression>>,
), ),
BooleanCast(Box<PlanExpression<I>>), BooleanCast(Box<PlanExpression>),
DoubleCast(Box<PlanExpression<I>>), DoubleCast(Box<PlanExpression>),
FloatCast(Box<PlanExpression<I>>), FloatCast(Box<PlanExpression>),
DecimalCast(Box<PlanExpression<I>>), DecimalCast(Box<PlanExpression>),
IntegerCast(Box<PlanExpression<I>>), IntegerCast(Box<PlanExpression>),
DateCast(Box<PlanExpression<I>>), DateCast(Box<PlanExpression>),
TimeCast(Box<PlanExpression<I>>), TimeCast(Box<PlanExpression>),
DateTimeCast(Box<PlanExpression<I>>), DateTimeCast(Box<PlanExpression>),
DurationCast(Box<PlanExpression<I>>), DurationCast(Box<PlanExpression>),
YearMonthDurationCast(Box<PlanExpression<I>>), YearMonthDurationCast(Box<PlanExpression>),
DayTimeDurationCast(Box<PlanExpression<I>>), DayTimeDurationCast(Box<PlanExpression>),
StringCast(Box<PlanExpression<I>>), StringCast(Box<PlanExpression>),
} }
impl<I: StrId> PlanExpression<I> { impl PlanExpression {
pub fn add_maybe_bound_variables(&self, set: &mut BTreeSet<usize>) { pub fn add_maybe_bound_variables(&self, set: &mut BTreeSet<usize>) {
match self { match self {
PlanExpression::Variable(v) | PlanExpression::Bound(v) => { PlanExpression::Variable(v) | PlanExpression::Bound(v) => {
@ -425,9 +425,9 @@ impl<I: StrId> PlanExpression<I> {
} }
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct PlanAggregation<I: StrId> { pub struct PlanAggregation {
pub function: PlanAggregationFunction, pub function: PlanAggregationFunction,
pub parameter: Option<PlanExpression<I>>, pub parameter: Option<PlanExpression>,
pub distinct: bool, pub distinct: bool,
} }
@ -443,43 +443,43 @@ pub enum PlanAggregationFunction {
} }
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum PlanPropertyPath<I: StrId> { pub enum PlanPropertyPath {
Path(EncodedTerm<I>), Path(EncodedTerm),
Reverse(Rc<PlanPropertyPath<I>>), Reverse(Rc<PlanPropertyPath>),
Sequence(Rc<PlanPropertyPath<I>>, Rc<PlanPropertyPath<I>>), Sequence(Rc<PlanPropertyPath>, Rc<PlanPropertyPath>),
Alternative(Rc<PlanPropertyPath<I>>, Rc<PlanPropertyPath<I>>), Alternative(Rc<PlanPropertyPath>, Rc<PlanPropertyPath>),
ZeroOrMore(Rc<PlanPropertyPath<I>>), ZeroOrMore(Rc<PlanPropertyPath>),
OneOrMore(Rc<PlanPropertyPath<I>>), OneOrMore(Rc<PlanPropertyPath>),
ZeroOrOne(Rc<PlanPropertyPath<I>>), ZeroOrOne(Rc<PlanPropertyPath>),
NegatedPropertySet(Rc<Vec<EncodedTerm<I>>>), NegatedPropertySet(Rc<Vec<EncodedTerm>>),
} }
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Comparator<I: StrId> { pub enum Comparator {
Asc(PlanExpression<I>), Asc(PlanExpression),
Desc(PlanExpression<I>), Desc(PlanExpression),
} }
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct TripleTemplate<I: StrId> { pub struct TripleTemplate {
pub subject: TripleTemplateValue<I>, pub subject: TripleTemplateValue,
pub predicate: TripleTemplateValue<I>, pub predicate: TripleTemplateValue,
pub object: TripleTemplateValue<I>, pub object: TripleTemplateValue,
} }
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub enum TripleTemplateValue<I: StrId> { pub enum TripleTemplateValue {
Constant(EncodedTerm<I>), Constant(EncodedTerm),
BlankNode(usize), BlankNode(usize),
Variable(usize), Variable(usize),
} }
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct EncodedTuple<I: StrId> { pub struct EncodedTuple {
inner: Vec<Option<EncodedTerm<I>>>, inner: Vec<Option<EncodedTerm>>,
} }
impl<I: StrId> EncodedTuple<I> { impl EncodedTuple {
pub fn with_capacity(capacity: usize) -> Self { pub fn with_capacity(capacity: usize) -> Self {
Self { Self {
inner: Vec::with_capacity(capacity), inner: Vec::with_capacity(capacity),
@ -494,15 +494,15 @@ impl<I: StrId> EncodedTuple<I> {
self.inner.get(index).map_or(false, Option::is_some) self.inner.get(index).map_or(false, Option::is_some)
} }
pub fn get(&self, index: usize) -> Option<EncodedTerm<I>> { pub fn get(&self, index: usize) -> Option<EncodedTerm> {
self.inner.get(index).cloned().unwrap_or(None) self.inner.get(index).cloned().unwrap_or(None)
} }
pub fn iter(&self) -> impl Iterator<Item = Option<EncodedTerm<I>>> + '_ { pub fn iter(&self) -> impl Iterator<Item = Option<EncodedTerm>> + '_ {
self.inner.iter().cloned() self.inner.iter().cloned()
} }
pub fn set(&mut self, index: usize, value: EncodedTerm<I>) { pub fn set(&mut self, index: usize, value: EncodedTerm) {
if self.inner.len() <= index { if self.inner.len() <= index {
self.inner.resize(index + 1, None); self.inner.resize(index + 1, None);
} }
@ -515,7 +515,7 @@ impl<I: StrId> EncodedTuple<I> {
} }
} }
pub fn combine_with(&self, other: &EncodedTuple<I>) -> Option<Self> { pub fn combine_with(&self, other: &EncodedTuple) -> Option<Self> {
if self.inner.len() < other.inner.len() { if self.inner.len() < other.inner.len() {
let mut result = other.inner.to_owned(); let mut result = other.inner.to_owned();
for (key, self_value) in self.inner.iter().enumerate() { for (key, self_value) in self.inner.iter().enumerate() {
@ -550,9 +550,9 @@ impl<I: StrId> EncodedTuple<I> {
} }
} }
impl<I: StrId> IntoIterator for EncodedTuple<I> { impl IntoIterator for EncodedTuple {
type Item = Option<EncodedTerm<I>>; type Item = Option<EncodedTerm>;
type IntoIter = std::vec::IntoIter<Option<EncodedTerm<I>>>; type IntoIter = std::vec::IntoIter<Option<EncodedTerm>>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter() self.inner.into_iter()

@ -15,7 +15,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
pub fn build( pub fn build(
encoder: E, encoder: E,
pattern: &GraphPattern, pattern: &GraphPattern,
) -> Result<(PlanNode<E::StrId>, Vec<Variable>), EvaluationError> { ) -> Result<(PlanNode, Vec<Variable>), EvaluationError> {
let mut variables = Vec::default(); let mut variables = Vec::default();
let plan = PlanBuilder { encoder }.build_for_graph_pattern( let plan = PlanBuilder { encoder }.build_for_graph_pattern(
pattern, pattern,
@ -29,7 +29,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
encoder: E, encoder: E,
template: &[TriplePattern], template: &[TriplePattern],
mut variables: Vec<Variable>, mut variables: Vec<Variable>,
) -> Result<Vec<TripleTemplate<E::StrId>>, EvaluationError> { ) -> Result<Vec<TripleTemplate>, EvaluationError> {
PlanBuilder { encoder }.build_for_graph_template(template, &mut variables) PlanBuilder { encoder }.build_for_graph_template(template, &mut variables)
} }
@ -37,8 +37,8 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
pattern: &GraphPattern, pattern: &GraphPattern,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue<E::StrId>, graph_name: PatternValue,
) -> Result<PlanNode<E::StrId>, EvaluationError> { ) -> Result<PlanNode, EvaluationError> {
Ok(match pattern { Ok(match pattern {
GraphPattern::BGP(p) => self.build_for_bgp(p, variables, graph_name)?, GraphPattern::BGP(p) => self.build_for_bgp(p, variables, graph_name)?,
GraphPattern::Path { GraphPattern::Path {
@ -268,8 +268,8 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
p: &[TriplePattern], p: &[TriplePattern],
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue<E::StrId>, graph_name: PatternValue,
) -> Result<PlanNode<E::StrId>, EvaluationError> { ) -> Result<PlanNode, EvaluationError> {
let mut plan = PlanNode::Init; let mut plan = PlanNode::Init;
for pattern in sort_bgp(p) { for pattern in sort_bgp(p) {
plan = PlanNode::QuadPatternJoin { plan = PlanNode::QuadPatternJoin {
@ -287,7 +287,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
fn build_for_path( fn build_for_path(
&mut self, &mut self,
path: &PropertyPathExpression, path: &PropertyPathExpression,
) -> Result<PlanPropertyPath<E::StrId>, EvaluationError> { ) -> Result<PlanPropertyPath, EvaluationError> {
Ok(match path { Ok(match path {
PropertyPathExpression::NamedNode(p) => { PropertyPathExpression::NamedNode(p) => {
PlanPropertyPath::Path(self.build_named_node(p)?) PlanPropertyPath::Path(self.build_named_node(p)?)
@ -326,8 +326,8 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
expression: &Expression, expression: &Expression,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue<E::StrId>, graph_name: PatternValue,
) -> Result<PlanExpression<E::StrId>, EvaluationError> { ) -> Result<PlanExpression, EvaluationError> {
Ok(match expression { Ok(match expression {
Expression::NamedNode(node) => PlanExpression::Constant(self.build_named_node(node)?), Expression::NamedNode(node) => PlanExpression::Constant(self.build_named_node(node)?),
Expression::Literal(l) => PlanExpression::Constant(self.build_literal(l)?), Expression::Literal(l) => PlanExpression::Constant(self.build_literal(l)?),
@ -728,11 +728,11 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
fn build_cast( fn build_cast(
&mut self, &mut self,
parameters: &[Expression], parameters: &[Expression],
constructor: impl Fn(Box<PlanExpression<E::StrId>>) -> PlanExpression<E::StrId>, constructor: impl Fn(Box<PlanExpression>) -> PlanExpression,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue<E::StrId>, graph_name: PatternValue,
name: &'static str, name: &'static str,
) -> Result<PlanExpression<E::StrId>, EvaluationError> { ) -> Result<PlanExpression, EvaluationError> {
if parameters.len() == 1 { if parameters.len() == 1 {
Ok(constructor(Box::new(self.build_for_expression( Ok(constructor(Box::new(self.build_for_expression(
&parameters[0], &parameters[0],
@ -751,8 +751,8 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
l: &[Expression], l: &[Expression],
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue<E::StrId>, graph_name: PatternValue,
) -> Result<Vec<PlanExpression<E::StrId>>, EvaluationError> { ) -> Result<Vec<PlanExpression>, EvaluationError> {
l.iter() l.iter()
.map(|e| self.build_for_expression(e, variables, graph_name)) .map(|e| self.build_for_expression(e, variables, graph_name))
.collect() .collect()
@ -762,7 +762,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
term_or_variable: &TermOrVariable, term_or_variable: &TermOrVariable,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
) -> Result<PatternValue<E::StrId>, EvaluationError> { ) -> Result<PatternValue, EvaluationError> {
Ok(match term_or_variable { Ok(match term_or_variable {
TermOrVariable::Variable(variable) => { TermOrVariable::Variable(variable) => {
PatternValue::Variable(variable_key(variables, variable)) PatternValue::Variable(variable_key(variables, variable))
@ -782,7 +782,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
named_node_or_variable: &NamedNodeOrVariable, named_node_or_variable: &NamedNodeOrVariable,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
) -> Result<PatternValue<E::StrId>, EvaluationError> { ) -> Result<PatternValue, EvaluationError> {
Ok(match named_node_or_variable { Ok(match named_node_or_variable {
NamedNodeOrVariable::NamedNode(named_node) => { NamedNodeOrVariable::NamedNode(named_node) => {
PatternValue::Constant(self.build_named_node(named_node)?) PatternValue::Constant(self.build_named_node(named_node)?)
@ -798,7 +798,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
table_variables: &[Variable], table_variables: &[Variable],
rows: &[Vec<Option<Term>>], rows: &[Vec<Option<Term>>],
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
) -> Result<Vec<EncodedTuple<E::StrId>>, EvaluationError> { ) -> Result<Vec<EncodedTuple>, EvaluationError> {
let bindings_variables_keys = table_variables let bindings_variables_keys = table_variables
.iter() .iter()
.map(|v| variable_key(variables, v)) .map(|v| variable_key(variables, v))
@ -820,8 +820,8 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
aggregate: &AggregationFunction, aggregate: &AggregationFunction,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue<E::StrId>, graph_name: PatternValue,
) -> Result<PlanAggregation<E::StrId>, EvaluationError> { ) -> Result<PlanAggregation, EvaluationError> {
match aggregate { match aggregate {
AggregationFunction::Count { expr, distinct } => Ok(PlanAggregation { AggregationFunction::Count { expr, distinct } => Ok(PlanAggregation {
function: PlanAggregationFunction::Count, function: PlanAggregationFunction::Count,
@ -877,7 +877,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
template: &[TriplePattern], template: &[TriplePattern],
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
) -> Result<Vec<TripleTemplate<E::StrId>>, EvaluationError> { ) -> Result<Vec<TripleTemplate>, EvaluationError> {
let mut bnodes = Vec::default(); let mut bnodes = Vec::default();
template template
.iter() .iter()
@ -905,7 +905,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
term_or_variable: &TermOrVariable, term_or_variable: &TermOrVariable,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
bnodes: &mut Vec<BlankNode>, bnodes: &mut Vec<BlankNode>,
) -> Result<TripleTemplateValue<E::StrId>, EvaluationError> { ) -> Result<TripleTemplateValue, EvaluationError> {
Ok(match term_or_variable { Ok(match term_or_variable {
TermOrVariable::Variable(variable) => { TermOrVariable::Variable(variable) => {
TripleTemplateValue::Variable(variable_key(variables, variable)) TripleTemplateValue::Variable(variable_key(variables, variable))
@ -921,7 +921,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
&mut self, &mut self,
named_node_or_variable: &NamedNodeOrVariable, named_node_or_variable: &NamedNodeOrVariable,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
) -> Result<TripleTemplateValue<E::StrId>, EvaluationError> { ) -> Result<TripleTemplateValue, EvaluationError> {
Ok(match named_node_or_variable { Ok(match named_node_or_variable {
NamedNodeOrVariable::Variable(variable) => { NamedNodeOrVariable::Variable(variable) => {
TripleTemplateValue::Variable(variable_key(variables, variable)) TripleTemplateValue::Variable(variable_key(variables, variable))
@ -934,10 +934,10 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
fn convert_pattern_value_id( fn convert_pattern_value_id(
&self, &self,
from_value: PatternValue<E::StrId>, from_value: PatternValue,
from: &[Variable], from: &[Variable],
to: &mut Vec<Variable>, to: &mut Vec<Variable>,
) -> PatternValue<E::StrId> { ) -> PatternValue {
match from_value { match from_value {
PatternValue::Constant(v) => PatternValue::Constant(v), PatternValue::Constant(v) => PatternValue::Constant(v),
PatternValue::Variable(from_id) => { PatternValue::Variable(from_id) => {
@ -966,11 +966,7 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
} }
} }
fn add_left_join_problematic_variables( fn add_left_join_problematic_variables(&self, node: &PlanNode, set: &mut BTreeSet<usize>) {
&self,
node: &PlanNode<E::StrId>,
set: &mut BTreeSet<usize>,
) {
match node { match node {
PlanNode::Init PlanNode::Init
| PlanNode::StaticBindings { .. } | PlanNode::StaticBindings { .. }
@ -1033,21 +1029,15 @@ impl<E: WriteEncoder<Error = EvaluationError>> PlanBuilder<E> {
} }
} }
fn build_named_node( fn build_named_node(&mut self, node: &NamedNode) -> Result<EncodedTerm, EvaluationError> {
&mut self,
node: &NamedNode,
) -> Result<EncodedTerm<E::StrId>, EvaluationError> {
self.encoder.encode_named_node(node.as_ref()) self.encoder.encode_named_node(node.as_ref())
} }
fn build_literal( fn build_literal(&mut self, literal: &Literal) -> Result<EncodedTerm, EvaluationError> {
&mut self,
literal: &Literal,
) -> Result<EncodedTerm<E::StrId>, EvaluationError> {
self.encoder.encode_literal(literal.as_ref()) self.encoder.encode_literal(literal.as_ref())
} }
fn build_term(&mut self, term: &Term) -> Result<EncodedTerm<E::StrId>, EvaluationError> { fn build_term(&mut self, term: &Term) -> Result<EncodedTerm, EvaluationError> {
self.encoder.encode_term(term.as_ref()) self.encoder.encode_term(term.as_ref())
} }
} }

@ -5,7 +5,7 @@ use crate::sparql::algebra::{
GraphPattern, GraphTarget, GraphUpdateOperation, NamedNodeOrVariable, QuadPattern, GraphPattern, GraphTarget, GraphUpdateOperation, NamedNodeOrVariable, QuadPattern,
QueryDataset, TermOrVariable, QueryDataset, TermOrVariable,
}; };
use crate::sparql::dataset::{DatasetStrId, DatasetView}; use crate::sparql::dataset::DatasetView;
use crate::sparql::eval::SimpleEvaluator; use crate::sparql::eval::SimpleEvaluator;
use crate::sparql::http::Client; use crate::sparql::http::Client;
use crate::sparql::plan::EncodedTuple; use crate::sparql::plan::EncodedTuple;
@ -33,7 +33,7 @@ pub(crate) struct SimpleUpdateEvaluator<'a, R, W> {
impl< impl<
'a, 'a,
R: ReadableEncodedStore + Clone + 'static, R: ReadableEncodedStore + Clone + 'static,
W: StrContainer<StrId = R::StrId> + WritableEncodedStore<StrId = R::StrId> + 'a, W: StrContainer + WritableEncodedStore + 'a,
> SimpleUpdateEvaluator<'a, R, W> > SimpleUpdateEvaluator<'a, R, W>
where where
io::Error: From<StoreOrParseError<W::Error>>, io::Error: From<StoreOrParseError<W::Error>>,
@ -127,28 +127,23 @@ where
.into_iter() .into_iter()
.map(|t| { .map(|t| {
Ok(if let Some(t) = t { Ok(if let Some(t) = t {
Some( t.on_each_id(|id| {
t.try_map_id(|id| { self.write
if let DatasetStrId::Store(s) = id { .insert_str(
Ok(s) &dataset
} else { .get_str(id)
self.write .map_err(to_eval_error)?
.insert_str( .ok_or_else(|| {
&dataset EvaluationError::msg(
.get_str(id) "String not stored in the string store",
.map_err(to_eval_error)? )
.ok_or_else(|| { })
EvaluationError::msg( .map_err(to_eval_error)?,
"String not stored in the string store", )
) .map(|_| ())
}) .map_err(to_eval_error)
.map_err(to_eval_error)?, })?;
) Some(t)
.map_err(to_eval_error)
}
})
.map_err(to_eval_error)?,
)
} else { } else {
None None
}) })
@ -356,7 +351,7 @@ where
&mut self, &mut self,
quad: &Quad, quad: &Quad,
bnodes: &mut HashMap<BlankNode, BlankNode>, bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> Result<Option<EncodedQuad<R::StrId>>, EvaluationError> { ) -> Result<Option<EncodedQuad>, EvaluationError> {
Ok(Some(EncodedQuad { Ok(Some(EncodedQuad {
subject: match &quad.subject { subject: match &quad.subject {
NamedOrBlankNode::NamedNode(subject) => { NamedOrBlankNode::NamedNode(subject) => {
@ -390,9 +385,9 @@ where
&mut self, &mut self,
quad: &QuadPattern, quad: &QuadPattern,
variables: &[Variable], variables: &[Variable],
values: &[Option<EncodedTerm<R::StrId>>], values: &[Option<EncodedTerm>],
bnodes: &mut HashMap<BlankNode, BlankNode>, bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> Result<Option<EncodedQuad<R::StrId>>, EvaluationError> { ) -> Result<Option<EncodedQuad>, EvaluationError> {
Ok(Some(EncodedQuad { Ok(Some(EncodedQuad {
subject: if let Some(subject) = subject: if let Some(subject) =
self.encode_term_for_insertion(&quad.subject, variables, values, bnodes, |t| { self.encode_term_for_insertion(&quad.subject, variables, values, bnodes, |t| {
@ -435,10 +430,10 @@ where
&mut self, &mut self,
term: &TermOrVariable, term: &TermOrVariable,
variables: &[Variable], variables: &[Variable],
values: &[Option<EncodedTerm<R::StrId>>], values: &[Option<EncodedTerm>],
bnodes: &mut HashMap<BlankNode, BlankNode>, bnodes: &mut HashMap<BlankNode, BlankNode>,
validate: impl FnOnce(&EncodedTerm<R::StrId>) -> bool, validate: impl FnOnce(&EncodedTerm) -> bool,
) -> Result<Option<EncodedTerm<R::StrId>>, EvaluationError> { ) -> Result<Option<EncodedTerm>, EvaluationError> {
Ok(match term { Ok(match term {
TermOrVariable::Term(term) => Some( TermOrVariable::Term(term) => Some(
self.write self.write
@ -471,8 +466,8 @@ where
&mut self, &mut self,
term: &NamedNodeOrVariable, term: &NamedNodeOrVariable,
variables: &[Variable], variables: &[Variable],
values: &[Option<EncodedTerm<R::StrId>>], values: &[Option<EncodedTerm>],
) -> Result<Option<EncodedTerm<R::StrId>>, EvaluationError> { ) -> Result<Option<EncodedTerm>, EvaluationError> {
Ok(match term { Ok(match term {
NamedNodeOrVariable::NamedNode(term) => Some( NamedNodeOrVariable::NamedNode(term) => Some(
self.write self.write
@ -500,7 +495,7 @@ where
fn encode_quad_for_deletion( fn encode_quad_for_deletion(
&mut self, &mut self,
quad: &Quad, quad: &Quad,
) -> Result<Option<EncodedQuad<R::StrId>>, EvaluationError> { ) -> Result<Option<EncodedQuad>, EvaluationError> {
Ok(Some(EncodedQuad { Ok(Some(EncodedQuad {
subject: if let Some(subject) = self subject: if let Some(subject) = self
.read .read
@ -545,8 +540,8 @@ where
&self, &self,
quad: &QuadPattern, quad: &QuadPattern,
variables: &[Variable], variables: &[Variable],
values: &[Option<EncodedTerm<R::StrId>>], values: &[Option<EncodedTerm>],
) -> Result<Option<EncodedQuad<R::StrId>>, EvaluationError> { ) -> Result<Option<EncodedQuad>, EvaluationError> {
Ok(Some(EncodedQuad { Ok(Some(EncodedQuad {
subject: if let Some(subject) = subject: if let Some(subject) =
self.encode_term_for_deletion(&quad.subject, variables, values)? self.encode_term_for_deletion(&quad.subject, variables, values)?
@ -587,8 +582,8 @@ where
&self, &self,
term: &TermOrVariable, term: &TermOrVariable,
variables: &[Variable], variables: &[Variable],
values: &[Option<EncodedTerm<R::StrId>>], values: &[Option<EncodedTerm>],
) -> Result<Option<EncodedTerm<R::StrId>>, EvaluationError> { ) -> Result<Option<EncodedTerm>, EvaluationError> {
match term { match term {
TermOrVariable::Term(term) => { TermOrVariable::Term(term) => {
if term.is_blank_node() { if term.is_blank_node() {
@ -619,8 +614,8 @@ where
&self, &self,
term: &NamedNodeOrVariable, term: &NamedNodeOrVariable,
variables: &[Variable], variables: &[Variable],
values: &[Option<EncodedTerm<R::StrId>>], values: &[Option<EncodedTerm>],
) -> Result<Option<EncodedTerm<R::StrId>>, EvaluationError> { ) -> Result<Option<EncodedTerm>, EvaluationError> {
Ok(match term { Ok(match term {
NamedNodeOrVariable::NamedNode(term) => self NamedNodeOrVariable::NamedNode(term) => self
.read .read

@ -6,8 +6,8 @@ use std::io;
use std::io::{Cursor, Read}; use std::io::{Cursor, Read};
use std::mem::size_of; use std::mem::size_of;
type EncodedTerm = crate::store::numeric_encoder::EncodedTerm<StrHash>; type EncodedTerm = crate::store::numeric_encoder::EncodedTerm;
type EncodedQuad = crate::store::numeric_encoder::EncodedQuad<StrHash>; type EncodedQuad = crate::store::numeric_encoder::EncodedQuad;
pub const LATEST_STORAGE_VERSION: u64 = 1; pub const LATEST_STORAGE_VERSION: u64 = 1;
pub const WRITTEN_TERM_MAX_SIZE: usize = size_of::<u8>() + 2 * size_of::<StrHash>(); pub const WRITTEN_TERM_MAX_SIZE: usize = size_of::<u8>() + 2 * size_of::<StrHash>();
@ -648,7 +648,6 @@ mod tests {
impl StrEncodingAware for MemoryStrStore { impl StrEncodingAware for MemoryStrStore {
type Error = Infallible; type Error = Infallible;
type StrId = StrHash;
} }
impl StrLookup for MemoryStrStore { impl StrLookup for MemoryStrStore {

@ -24,44 +24,32 @@ use std::io::{BufRead, Write};
use std::iter::Iterator; use std::iter::Iterator;
pub(crate) trait ReadableEncodedStore: StrLookup { pub(crate) trait ReadableEncodedStore: StrLookup {
type QuadsIter: Iterator<Item = Result<EncodedQuad<Self::StrId>, Self::Error>> + 'static; type QuadsIter: Iterator<Item = Result<EncodedQuad, Self::Error>> + 'static;
type GraphsIter: Iterator<Item = Result<EncodedTerm<Self::StrId>, Self::Error>> + 'static; type GraphsIter: Iterator<Item = Result<EncodedTerm, Self::Error>> + 'static;
fn encoded_quads_for_pattern( fn encoded_quads_for_pattern(
&self, &self,
subject: Option<EncodedTerm<Self::StrId>>, subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm<Self::StrId>>, predicate: Option<EncodedTerm>,
object: Option<EncodedTerm<Self::StrId>>, object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm<Self::StrId>>, graph_name: Option<EncodedTerm>,
) -> Self::QuadsIter; ) -> Self::QuadsIter;
fn encoded_named_graphs(&self) -> Self::GraphsIter; fn encoded_named_graphs(&self) -> Self::GraphsIter;
fn contains_encoded_named_graph( fn contains_encoded_named_graph(&self, graph_name: EncodedTerm) -> Result<bool, Self::Error>;
&self,
graph_name: EncodedTerm<Self::StrId>,
) -> Result<bool, Self::Error>;
} }
pub(crate) trait WritableEncodedStore: StrEncodingAware { pub(crate) trait WritableEncodedStore: StrEncodingAware {
fn insert_encoded(&mut self, quad: &EncodedQuad<Self::StrId>) -> Result<(), Self::Error>; fn insert_encoded(&mut self, quad: &EncodedQuad) -> Result<(), Self::Error>;
fn remove_encoded(&mut self, quad: &EncodedQuad<Self::StrId>) -> Result<(), Self::Error>; fn remove_encoded(&mut self, quad: &EncodedQuad) -> Result<(), Self::Error>;
fn insert_encoded_named_graph( fn insert_encoded_named_graph(&mut self, graph_name: EncodedTerm) -> Result<(), Self::Error>;
&mut self,
graph_name: EncodedTerm<Self::StrId>,
) -> Result<(), Self::Error>;
fn clear_encoded_graph( fn clear_encoded_graph(&mut self, graph_name: EncodedTerm) -> Result<(), Self::Error>;
&mut self,
graph_name: EncodedTerm<Self::StrId>,
) -> Result<(), Self::Error>;
fn remove_encoded_named_graph( fn remove_encoded_named_graph(&mut self, graph_name: EncodedTerm) -> Result<(), Self::Error>;
&mut self,
graph_name: EncodedTerm<Self::StrId>,
) -> Result<(), Self::Error>;
fn clear(&mut self) -> Result<(), Self::Error>; fn clear(&mut self) -> Result<(), Self::Error>;
} }
@ -215,11 +203,11 @@ impl From<StoreOrParseError<Infallible>> for io::Error {
} }
} }
type QuadPattern<I> = ( type QuadPattern = (
Option<EncodedTerm<I>>, Option<EncodedTerm>,
Option<EncodedTerm<I>>, Option<EncodedTerm>,
Option<EncodedTerm<I>>, Option<EncodedTerm>,
Option<EncodedTerm<I>>, Option<EncodedTerm>,
); );
fn get_encoded_quad_pattern<E: ReadEncoder>( fn get_encoded_quad_pattern<E: ReadEncoder>(
@ -228,7 +216,7 @@ fn get_encoded_quad_pattern<E: ReadEncoder>(
predicate: Option<NamedNodeRef<'_>>, predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>, object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>, graph_name: Option<GraphNameRef<'_>>,
) -> Result<Option<QuadPattern<E::StrId>>, E::Error> { ) -> Result<Option<QuadPattern>, E::Error> {
Ok(Some(( Ok(Some((
if let Some(subject) = transpose( if let Some(subject) = transpose(
subject subject

@ -16,8 +16,6 @@ use std::hash::Hash;
use std::hash::Hasher; use std::hash::Hasher;
use std::{fmt, io, str}; use std::{fmt, io, str};
pub trait StrId: Eq + Debug + Copy + Hash {}
#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)]
#[repr(transparent)] #[repr(transparent)]
pub struct StrHash { pub struct StrHash {
@ -46,24 +44,22 @@ impl StrHash {
} }
} }
impl StrId for StrHash {}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum EncodedTerm<I: StrId> { pub enum EncodedTerm {
DefaultGraph, DefaultGraph,
NamedNode { NamedNode {
iri_id: I, iri_id: StrHash,
}, },
NumericalBlankNode { NumericalBlankNode {
id: u128, id: u128,
}, },
SmallBlankNode(SmallString), SmallBlankNode(SmallString),
BigBlankNode { BigBlankNode {
id_id: I, id_id: StrHash,
}, },
SmallStringLiteral(SmallString), SmallStringLiteral(SmallString),
BigStringLiteral { BigStringLiteral {
value_id: I, value_id: StrHash,
}, },
SmallSmallLangStringLiteral { SmallSmallLangStringLiteral {
value: SmallString, value: SmallString,
@ -71,23 +67,23 @@ pub enum EncodedTerm<I: StrId> {
}, },
SmallBigLangStringLiteral { SmallBigLangStringLiteral {
value: SmallString, value: SmallString,
language_id: I, language_id: StrHash,
}, },
BigSmallLangStringLiteral { BigSmallLangStringLiteral {
value_id: I, value_id: StrHash,
language: SmallString, language: SmallString,
}, },
BigBigLangStringLiteral { BigBigLangStringLiteral {
value_id: I, value_id: StrHash,
language_id: I, language_id: StrHash,
}, },
SmallTypedLiteral { SmallTypedLiteral {
value: SmallString, value: SmallString,
datatype_id: I, datatype_id: StrHash,
}, },
BigTypedLiteral { BigTypedLiteral {
value_id: I, value_id: StrHash,
datatype_id: I, datatype_id: StrHash,
}, },
BooleanLiteral(bool), BooleanLiteral(bool),
FloatLiteral(f32), FloatLiteral(f32),
@ -107,7 +103,7 @@ pub enum EncodedTerm<I: StrId> {
DayTimeDurationLiteral(DayTimeDuration), DayTimeDurationLiteral(DayTimeDuration),
} }
impl<I: StrId> PartialEq for EncodedTerm<I> { impl PartialEq for EncodedTerm {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
match (self, other) { match (self, other) {
(Self::DefaultGraph, Self::DefaultGraph) => true, (Self::DefaultGraph, Self::DefaultGraph) => true,
@ -223,9 +219,9 @@ impl<I: StrId> PartialEq for EncodedTerm<I> {
} }
} }
impl<I: StrId> Eq for EncodedTerm<I> {} impl Eq for EncodedTerm {}
impl<I: StrId> Hash for EncodedTerm<I> { impl Hash for EncodedTerm {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
match self { match self {
Self::NamedNode { iri_id } => iri_id.hash(state), Self::NamedNode { iri_id } => iri_id.hash(state),
@ -285,7 +281,7 @@ impl<I: StrId> Hash for EncodedTerm<I> {
} }
} }
impl<I: StrId> EncodedTerm<I> { impl EncodedTerm {
pub fn is_named_node(&self) -> bool { pub fn is_named_node(&self) -> bool {
matches!(self, Self::NamedNode { .. }) matches!(self, Self::NamedNode { .. })
} }
@ -340,241 +336,146 @@ impl<I: StrId> EncodedTerm<I> {
matches!(self, Self::DefaultGraph) matches!(self, Self::DefaultGraph)
} }
pub fn map_id<J: StrId>(self, mapping: impl Fn(I) -> J) -> EncodedTerm<J> { pub fn on_each_id<E>(
self,
mut callback: impl FnMut(StrHash) -> Result<(), E>,
) -> Result<(), E> {
match self { match self {
Self::DefaultGraph { .. } => EncodedTerm::DefaultGraph, Self::NamedNode { iri_id } => {
Self::NamedNode { iri_id } => EncodedTerm::NamedNode { callback(iri_id)?;
iri_id: mapping(iri_id),
},
Self::NumericalBlankNode { id } => EncodedTerm::NumericalBlankNode { id },
Self::SmallBlankNode(id) => EncodedTerm::SmallBlankNode(id),
Self::BigBlankNode { id_id } => EncodedTerm::BigBlankNode {
id_id: mapping(id_id),
},
Self::SmallStringLiteral(value) => EncodedTerm::SmallStringLiteral(value),
Self::BigStringLiteral { value_id } => EncodedTerm::BigStringLiteral {
value_id: mapping(value_id),
},
Self::SmallSmallLangStringLiteral { value, language } => {
EncodedTerm::SmallSmallLangStringLiteral { value, language }
} }
Self::SmallBigLangStringLiteral { value, language_id } => { Self::BigBlankNode { id_id } => {
EncodedTerm::SmallBigLangStringLiteral { callback(id_id)?;
value,
language_id: mapping(language_id),
}
} }
Self::BigSmallLangStringLiteral { value_id, language } => { Self::BigStringLiteral { value_id } => {
EncodedTerm::BigSmallLangStringLiteral { callback(value_id)?;
value_id: mapping(value_id),
language,
}
} }
Self::BigBigLangStringLiteral { Self::SmallBigLangStringLiteral { language_id, .. } => {
value_id, callback(language_id)?;
language_id,
} => EncodedTerm::BigBigLangStringLiteral {
value_id: mapping(value_id),
language_id: mapping(language_id),
},
Self::SmallTypedLiteral { value, datatype_id } => EncodedTerm::SmallTypedLiteral {
value,
datatype_id: mapping(datatype_id),
},
Self::BigTypedLiteral {
value_id,
datatype_id,
} => EncodedTerm::BigTypedLiteral {
value_id: mapping(value_id),
datatype_id: mapping(datatype_id),
},
Self::BooleanLiteral(value) => EncodedTerm::BooleanLiteral(value),
Self::FloatLiteral(value) => EncodedTerm::FloatLiteral(value),
Self::DoubleLiteral(value) => EncodedTerm::DoubleLiteral(value),
Self::IntegerLiteral(value) => EncodedTerm::IntegerLiteral(value),
Self::DecimalLiteral(value) => EncodedTerm::DecimalLiteral(value),
Self::DateTimeLiteral(value) => EncodedTerm::DateTimeLiteral(value),
Self::DateLiteral(value) => EncodedTerm::DateLiteral(value),
Self::TimeLiteral(value) => EncodedTerm::TimeLiteral(value),
Self::GYearMonthLiteral(value) => EncodedTerm::GYearMonthLiteral(value),
Self::GYearLiteral(value) => EncodedTerm::GYearLiteral(value),
Self::GMonthDayLiteral(value) => EncodedTerm::GMonthDayLiteral(value),
Self::GDayLiteral(value) => EncodedTerm::GDayLiteral(value),
Self::GMonthLiteral(value) => EncodedTerm::GMonthLiteral(value),
Self::DurationLiteral(value) => EncodedTerm::DurationLiteral(value),
Self::YearMonthDurationLiteral(value) => EncodedTerm::YearMonthDurationLiteral(value),
Self::DayTimeDurationLiteral(value) => EncodedTerm::DayTimeDurationLiteral(value),
}
}
pub fn try_map_id<J: StrId, E>(
self,
mut mapping: impl FnMut(I) -> Result<J, E>,
) -> Result<EncodedTerm<J>, E> {
Ok(match self {
Self::DefaultGraph { .. } => EncodedTerm::DefaultGraph,
Self::NamedNode { iri_id } => EncodedTerm::NamedNode {
iri_id: mapping(iri_id)?,
},
Self::NumericalBlankNode { id } => EncodedTerm::NumericalBlankNode { id },
Self::SmallBlankNode(id) => EncodedTerm::SmallBlankNode(id),
Self::BigBlankNode { id_id } => EncodedTerm::BigBlankNode {
id_id: mapping(id_id)?,
},
Self::SmallStringLiteral(value) => EncodedTerm::SmallStringLiteral(value),
Self::BigStringLiteral { value_id } => EncodedTerm::BigStringLiteral {
value_id: mapping(value_id)?,
},
Self::SmallSmallLangStringLiteral { value, language } => {
EncodedTerm::SmallSmallLangStringLiteral { value, language }
} }
Self::SmallBigLangStringLiteral { value, language_id } => { Self::BigSmallLangStringLiteral { value_id, .. } => {
EncodedTerm::SmallBigLangStringLiteral { callback(value_id)?;
value,
language_id: mapping(language_id)?,
}
}
Self::BigSmallLangStringLiteral { value_id, language } => {
EncodedTerm::BigSmallLangStringLiteral {
value_id: mapping(value_id)?,
language,
}
} }
Self::BigBigLangStringLiteral { Self::BigBigLangStringLiteral {
value_id, value_id,
language_id, language_id,
} => EncodedTerm::BigBigLangStringLiteral { } => {
value_id: mapping(value_id)?, callback(value_id)?;
language_id: mapping(language_id)?, callback(language_id)?;
}, }
Self::SmallTypedLiteral { value, datatype_id } => EncodedTerm::SmallTypedLiteral { Self::SmallTypedLiteral { datatype_id, .. } => {
value, callback(datatype_id)?;
datatype_id: mapping(datatype_id)?, }
},
Self::BigTypedLiteral { Self::BigTypedLiteral {
value_id, value_id,
datatype_id, datatype_id,
} => EncodedTerm::BigTypedLiteral { } => {
value_id: mapping(value_id)?, callback(value_id)?;
datatype_id: mapping(datatype_id)?, callback(datatype_id)?;
}, }
Self::BooleanLiteral(value) => EncodedTerm::BooleanLiteral(value), _ => (),
Self::FloatLiteral(value) => EncodedTerm::FloatLiteral(value), }
Self::DoubleLiteral(value) => EncodedTerm::DoubleLiteral(value), Ok(())
Self::IntegerLiteral(value) => EncodedTerm::IntegerLiteral(value),
Self::DecimalLiteral(value) => EncodedTerm::DecimalLiteral(value),
Self::DateTimeLiteral(value) => EncodedTerm::DateTimeLiteral(value),
Self::DateLiteral(value) => EncodedTerm::DateLiteral(value),
Self::TimeLiteral(value) => EncodedTerm::TimeLiteral(value),
Self::GYearMonthLiteral(value) => EncodedTerm::GYearMonthLiteral(value),
Self::GYearLiteral(value) => EncodedTerm::GYearLiteral(value),
Self::GMonthDayLiteral(value) => EncodedTerm::GMonthDayLiteral(value),
Self::GDayLiteral(value) => EncodedTerm::GDayLiteral(value),
Self::GMonthLiteral(value) => EncodedTerm::GMonthLiteral(value),
Self::DurationLiteral(value) => EncodedTerm::DurationLiteral(value),
Self::YearMonthDurationLiteral(value) => EncodedTerm::YearMonthDurationLiteral(value),
Self::DayTimeDurationLiteral(value) => EncodedTerm::DayTimeDurationLiteral(value),
})
} }
} }
impl<I: StrId> From<bool> for EncodedTerm<I> { impl From<bool> for EncodedTerm {
fn from(value: bool) -> Self { fn from(value: bool) -> Self {
Self::BooleanLiteral(value) Self::BooleanLiteral(value)
} }
} }
impl<I: StrId> From<i64> for EncodedTerm<I> { impl From<i64> for EncodedTerm {
fn from(value: i64) -> Self { fn from(value: i64) -> Self {
Self::IntegerLiteral(value) Self::IntegerLiteral(value)
} }
} }
impl<I: StrId> From<i32> for EncodedTerm<I> { impl From<i32> for EncodedTerm {
fn from(value: i32) -> Self { fn from(value: i32) -> Self {
Self::IntegerLiteral(value.into()) Self::IntegerLiteral(value.into())
} }
} }
impl<I: StrId> From<u32> for EncodedTerm<I> { impl From<u32> for EncodedTerm {
fn from(value: u32) -> Self { fn from(value: u32) -> Self {
Self::IntegerLiteral(value.into()) Self::IntegerLiteral(value.into())
} }
} }
impl<I: StrId> From<u8> for EncodedTerm<I> { impl From<u8> for EncodedTerm {
fn from(value: u8) -> Self { fn from(value: u8) -> Self {
Self::IntegerLiteral(value.into()) Self::IntegerLiteral(value.into())
} }
} }
impl<I: StrId> From<f32> for EncodedTerm<I> { impl From<f32> for EncodedTerm {
fn from(value: f32) -> Self { fn from(value: f32) -> Self {
Self::FloatLiteral(value) Self::FloatLiteral(value)
} }
} }
impl<I: StrId> From<f64> for EncodedTerm<I> { impl From<f64> for EncodedTerm {
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
Self::DoubleLiteral(value) Self::DoubleLiteral(value)
} }
} }
impl<I: StrId> From<Decimal> for EncodedTerm<I> { impl From<Decimal> for EncodedTerm {
fn from(value: Decimal) -> Self { fn from(value: Decimal) -> Self {
Self::DecimalLiteral(value) Self::DecimalLiteral(value)
} }
} }
impl<I: StrId> From<DateTime> for EncodedTerm<I> { impl From<DateTime> for EncodedTerm {
fn from(value: DateTime) -> Self { fn from(value: DateTime) -> Self {
Self::DateTimeLiteral(value) Self::DateTimeLiteral(value)
} }
} }
impl<I: StrId> From<Time> for EncodedTerm<I> { impl From<Time> for EncodedTerm {
fn from(value: Time) -> Self { fn from(value: Time) -> Self {
Self::TimeLiteral(value) Self::TimeLiteral(value)
} }
} }
impl<I: StrId> From<Date> for EncodedTerm<I> { impl From<Date> for EncodedTerm {
fn from(value: Date) -> Self { fn from(value: Date) -> Self {
Self::DateLiteral(value) Self::DateLiteral(value)
} }
} }
impl<I: StrId> From<Duration> for EncodedTerm<I> { impl From<Duration> for EncodedTerm {
fn from(value: Duration) -> Self { fn from(value: Duration) -> Self {
Self::DurationLiteral(value) Self::DurationLiteral(value)
} }
} }
impl<I: StrId> From<YearMonthDuration> for EncodedTerm<I> { impl From<YearMonthDuration> for EncodedTerm {
fn from(value: YearMonthDuration) -> Self { fn from(value: YearMonthDuration) -> Self {
Self::YearMonthDurationLiteral(value) Self::YearMonthDurationLiteral(value)
} }
} }
impl<I: StrId> From<DayTimeDuration> for EncodedTerm<I> { impl From<DayTimeDuration> for EncodedTerm {
fn from(value: DayTimeDuration) -> Self { fn from(value: DayTimeDuration) -> Self {
Self::DayTimeDurationLiteral(value) Self::DayTimeDurationLiteral(value)
} }
} }
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct EncodedQuad<I: StrId> { pub struct EncodedQuad {
pub subject: EncodedTerm<I>, pub subject: EncodedTerm,
pub predicate: EncodedTerm<I>, pub predicate: EncodedTerm,
pub object: EncodedTerm<I>, pub object: EncodedTerm,
pub graph_name: EncodedTerm<I>, pub graph_name: EncodedTerm,
} }
impl<I: StrId> EncodedQuad<I> { impl EncodedQuad {
pub fn new( pub fn new(
subject: EncodedTerm<I>, subject: EncodedTerm,
predicate: EncodedTerm<I>, predicate: EncodedTerm,
object: EncodedTerm<I>, object: EncodedTerm,
graph_name: EncodedTerm<I>, graph_name: EncodedTerm,
) -> Self { ) -> Self {
Self { Self {
subject, subject,
@ -588,22 +489,20 @@ impl<I: StrId> EncodedQuad<I> {
pub(crate) trait StrEncodingAware { pub(crate) trait StrEncodingAware {
//TODO: rename //TODO: rename
type Error: Error + Into<EvaluationError> + 'static; type Error: Error + Into<EvaluationError> + 'static;
type StrId: StrId + 'static;
} }
impl<'a, T: StrEncodingAware> StrEncodingAware for &'a T { impl<'a, T: StrEncodingAware> StrEncodingAware for &'a T {
type Error = T::Error; type Error = T::Error;
type StrId = T::StrId;
} }
pub(crate) trait StrLookup: StrEncodingAware { pub(crate) trait StrLookup: StrEncodingAware {
fn get_str(&self, id: Self::StrId) -> Result<Option<String>, Self::Error>; fn get_str(&self, id: StrHash) -> Result<Option<String>, Self::Error>;
fn get_str_id(&self, value: &str) -> Result<Option<Self::StrId>, Self::Error>; fn get_str_id(&self, value: &str) -> Result<Option<StrHash>, Self::Error>;
} }
pub(crate) trait StrContainer: StrEncodingAware { pub(crate) trait StrContainer: StrEncodingAware {
fn insert_str(&mut self, value: &str) -> Result<Self::StrId, Self::Error>; fn insert_str(&mut self, value: &str) -> Result<StrHash, Self::Error>;
} }
/// Tries to encode a term based on the existing strings (does not insert anything) /// Tries to encode a term based on the existing strings (does not insert anything)
@ -611,7 +510,7 @@ pub(crate) trait ReadEncoder: StrEncodingAware {
fn get_encoded_named_node( fn get_encoded_named_node(
&self, &self,
named_node: NamedNodeRef<'_>, named_node: NamedNodeRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> { ) -> Result<Option<EncodedTerm>, Self::Error> {
Ok(Some(EncodedTerm::NamedNode { Ok(Some(EncodedTerm::NamedNode {
iri_id: if let Some(iri_id) = self.get_encoded_str(named_node.as_str())? { iri_id: if let Some(iri_id) = self.get_encoded_str(named_node.as_str())? {
iri_id iri_id
@ -624,7 +523,7 @@ pub(crate) trait ReadEncoder: StrEncodingAware {
fn get_encoded_blank_node( fn get_encoded_blank_node(
&self, &self,
blank_node: BlankNodeRef<'_>, blank_node: BlankNodeRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> { ) -> Result<Option<EncodedTerm>, Self::Error> {
Ok(Some(if let Some(id) = blank_node.id() { Ok(Some(if let Some(id) = blank_node.id() {
EncodedTerm::NumericalBlankNode { id } EncodedTerm::NumericalBlankNode { id }
} else { } else {
@ -646,7 +545,7 @@ pub(crate) trait ReadEncoder: StrEncodingAware {
fn get_encoded_literal( fn get_encoded_literal(
&self, &self,
literal: LiteralRef<'_>, literal: LiteralRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> { ) -> Result<Option<EncodedTerm>, Self::Error> {
let value = literal.value(); let value = literal.value();
let datatype = literal.datatype().as_str(); let datatype = literal.datatype().as_str();
Ok(Some( Ok(Some(
@ -783,17 +682,14 @@ pub(crate) trait ReadEncoder: StrEncodingAware {
fn get_encoded_named_or_blank_node( fn get_encoded_named_or_blank_node(
&self, &self,
term: NamedOrBlankNodeRef<'_>, term: NamedOrBlankNodeRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> { ) -> Result<Option<EncodedTerm>, Self::Error> {
match term { match term {
NamedOrBlankNodeRef::NamedNode(named_node) => self.get_encoded_named_node(named_node), NamedOrBlankNodeRef::NamedNode(named_node) => self.get_encoded_named_node(named_node),
NamedOrBlankNodeRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node), NamedOrBlankNodeRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
} }
} }
fn get_encoded_term( fn get_encoded_term(&self, term: TermRef<'_>) -> Result<Option<EncodedTerm>, Self::Error> {
&self,
term: TermRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> {
match term { match term {
TermRef::NamedNode(named_node) => self.get_encoded_named_node(named_node), TermRef::NamedNode(named_node) => self.get_encoded_named_node(named_node),
TermRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node), TermRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
@ -804,7 +700,7 @@ pub(crate) trait ReadEncoder: StrEncodingAware {
fn get_encoded_graph_name( fn get_encoded_graph_name(
&self, &self,
name: GraphNameRef<'_>, name: GraphNameRef<'_>,
) -> Result<Option<EncodedTerm<Self::StrId>>, Self::Error> { ) -> Result<Option<EncodedTerm>, Self::Error> {
match name { match name {
GraphNameRef::NamedNode(named_node) => self.get_encoded_named_node(named_node), GraphNameRef::NamedNode(named_node) => self.get_encoded_named_node(named_node),
GraphNameRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node), GraphNameRef::BlankNode(blank_node) => self.get_encoded_blank_node(blank_node),
@ -812,10 +708,7 @@ pub(crate) trait ReadEncoder: StrEncodingAware {
} }
} }
fn get_encoded_quad( fn get_encoded_quad(&self, quad: QuadRef<'_>) -> Result<Option<EncodedQuad>, Self::Error> {
&self,
quad: QuadRef<'_>,
) -> Result<Option<EncodedQuad<Self::StrId>>, Self::Error> {
Ok(Some(EncodedQuad { Ok(Some(EncodedQuad {
subject: if let Some(subject) = self.get_encoded_named_or_blank_node(quad.subject)? { subject: if let Some(subject) = self.get_encoded_named_or_blank_node(quad.subject)? {
subject subject
@ -840,11 +733,11 @@ pub(crate) trait ReadEncoder: StrEncodingAware {
})) }))
} }
fn get_encoded_str(&self, value: &str) -> Result<Option<Self::StrId>, Self::Error>; fn get_encoded_str(&self, value: &str) -> Result<Option<StrHash>, Self::Error>;
} }
impl<S: StrLookup> ReadEncoder for S { impl<S: StrLookup> ReadEncoder for S {
fn get_encoded_str(&self, value: &str) -> Result<Option<Self::StrId>, Self::Error> { fn get_encoded_str(&self, value: &str) -> Result<Option<StrHash>, Self::Error> {
self.get_str_id(value) self.get_str_id(value)
} }
} }
@ -854,14 +747,14 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
fn encode_named_node( fn encode_named_node(
&mut self, &mut self,
named_node: NamedNodeRef<'_>, named_node: NamedNodeRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> { ) -> Result<EncodedTerm, Self::Error> {
self.encode_rio_named_node(named_node.into()) self.encode_rio_named_node(named_node.into())
} }
fn encode_blank_node( fn encode_blank_node(
&mut self, &mut self,
blank_node: BlankNodeRef<'_>, blank_node: BlankNodeRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> { ) -> Result<EncodedTerm, Self::Error> {
Ok(if let Some(id) = blank_node.id() { Ok(if let Some(id) = blank_node.id() {
EncodedTerm::NumericalBlankNode { id } EncodedTerm::NumericalBlankNode { id }
} else { } else {
@ -876,24 +769,21 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
}) })
} }
fn encode_literal( fn encode_literal(&mut self, literal: LiteralRef<'_>) -> Result<EncodedTerm, Self::Error> {
&mut self,
literal: LiteralRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
self.encode_rio_literal(literal.into()) self.encode_rio_literal(literal.into())
} }
fn encode_named_or_blank_node( fn encode_named_or_blank_node(
&mut self, &mut self,
term: NamedOrBlankNodeRef<'_>, term: NamedOrBlankNodeRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> { ) -> Result<EncodedTerm, Self::Error> {
match term { match term {
NamedOrBlankNodeRef::NamedNode(named_node) => self.encode_named_node(named_node), NamedOrBlankNodeRef::NamedNode(named_node) => self.encode_named_node(named_node),
NamedOrBlankNodeRef::BlankNode(blank_node) => self.encode_blank_node(blank_node), NamedOrBlankNodeRef::BlankNode(blank_node) => self.encode_blank_node(blank_node),
} }
} }
fn encode_term(&mut self, term: TermRef<'_>) -> Result<EncodedTerm<Self::StrId>, Self::Error> { fn encode_term(&mut self, term: TermRef<'_>) -> Result<EncodedTerm, Self::Error> {
match term { match term {
TermRef::NamedNode(named_node) => self.encode_named_node(named_node), TermRef::NamedNode(named_node) => self.encode_named_node(named_node),
TermRef::BlankNode(blank_node) => self.encode_blank_node(blank_node), TermRef::BlankNode(blank_node) => self.encode_blank_node(blank_node),
@ -901,10 +791,7 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
} }
} }
fn encode_graph_name( fn encode_graph_name(&mut self, name: GraphNameRef<'_>) -> Result<EncodedTerm, Self::Error> {
&mut self,
name: GraphNameRef<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> {
match name { match name {
GraphNameRef::NamedNode(named_node) => self.encode_named_node(named_node), GraphNameRef::NamedNode(named_node) => self.encode_named_node(named_node),
GraphNameRef::BlankNode(blank_node) => self.encode_blank_node(blank_node), GraphNameRef::BlankNode(blank_node) => self.encode_blank_node(blank_node),
@ -912,7 +799,7 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
} }
} }
fn encode_quad(&mut self, quad: QuadRef<'_>) -> Result<EncodedQuad<Self::StrId>, Self::Error> { fn encode_quad(&mut self, quad: QuadRef<'_>) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad { Ok(EncodedQuad {
subject: self.encode_named_or_blank_node(quad.subject)?, subject: self.encode_named_or_blank_node(quad.subject)?,
predicate: self.encode_named_node(quad.predicate)?, predicate: self.encode_named_node(quad.predicate)?,
@ -924,8 +811,8 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
fn encode_triple_in_graph( fn encode_triple_in_graph(
&mut self, &mut self,
triple: TripleRef<'_>, triple: TripleRef<'_>,
graph_name: EncodedTerm<Self::StrId>, graph_name: EncodedTerm,
) -> Result<EncodedQuad<Self::StrId>, Self::Error> { ) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad { Ok(EncodedQuad {
subject: self.encode_named_or_blank_node(triple.subject)?, subject: self.encode_named_or_blank_node(triple.subject)?,
predicate: self.encode_named_node(triple.predicate)?, predicate: self.encode_named_node(triple.predicate)?,
@ -937,7 +824,7 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
fn encode_rio_named_node( fn encode_rio_named_node(
&mut self, &mut self,
named_node: rio::NamedNode<'_>, named_node: rio::NamedNode<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> { ) -> Result<EncodedTerm, Self::Error> {
Ok(EncodedTerm::NamedNode { Ok(EncodedTerm::NamedNode {
iri_id: self.encode_str(named_node.iri)?, iri_id: self.encode_str(named_node.iri)?,
}) })
@ -947,7 +834,7 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
&mut self, &mut self,
blank_node: rio::BlankNode<'_>, blank_node: rio::BlankNode<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> { ) -> Result<EncodedTerm, Self::Error> {
Ok(if let Some(id) = bnodes_map.get(blank_node.id) { Ok(if let Some(id) = bnodes_map.get(blank_node.id) {
EncodedTerm::NumericalBlankNode { id: *id } EncodedTerm::NumericalBlankNode { id: *id }
} else { } else {
@ -959,7 +846,7 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
fn encode_rio_literal( fn encode_rio_literal(
&mut self, &mut self,
literal: rio::Literal<'_>, literal: rio::Literal<'_>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> { ) -> Result<EncodedTerm, Self::Error> {
Ok(match literal { Ok(match literal {
rio::Literal::Simple { value } => { rio::Literal::Simple { value } => {
if let Ok(value) = SmallString::try_from(value) { if let Ok(value) = SmallString::try_from(value) {
@ -1065,7 +952,7 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
&mut self, &mut self,
term: rio::NamedOrBlankNode<'_>, term: rio::NamedOrBlankNode<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> { ) -> Result<EncodedTerm, Self::Error> {
match term { match term {
rio::NamedOrBlankNode::NamedNode(named_node) => self.encode_rio_named_node(named_node), rio::NamedOrBlankNode::NamedNode(named_node) => self.encode_rio_named_node(named_node),
rio::NamedOrBlankNode::BlankNode(blank_node) => { rio::NamedOrBlankNode::BlankNode(blank_node) => {
@ -1078,7 +965,7 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
&mut self, &mut self,
term: rio::Term<'_>, term: rio::Term<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedTerm<Self::StrId>, Self::Error> { ) -> Result<EncodedTerm, Self::Error> {
match term { match term {
rio::Term::NamedNode(named_node) => self.encode_rio_named_node(named_node), rio::Term::NamedNode(named_node) => self.encode_rio_named_node(named_node),
rio::Term::BlankNode(blank_node) => self.encode_rio_blank_node(blank_node, bnodes_map), rio::Term::BlankNode(blank_node) => self.encode_rio_blank_node(blank_node, bnodes_map),
@ -1090,7 +977,7 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
&mut self, &mut self,
quad: rio::Quad<'_>, quad: rio::Quad<'_>,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedQuad<Self::StrId>, Self::Error> { ) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad { Ok(EncodedQuad {
subject: self.encode_rio_named_or_blank_node(quad.subject, bnodes_map)?, subject: self.encode_rio_named_or_blank_node(quad.subject, bnodes_map)?,
predicate: self.encode_rio_named_node(quad.predicate)?, predicate: self.encode_rio_named_node(quad.predicate)?,
@ -1105,9 +992,9 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
fn encode_rio_triple_in_graph( fn encode_rio_triple_in_graph(
&mut self, &mut self,
triple: rio::Triple<'_>, triple: rio::Triple<'_>,
graph_name: EncodedTerm<Self::StrId>, graph_name: EncodedTerm,
bnodes_map: &mut HashMap<String, u128>, bnodes_map: &mut HashMap<String, u128>,
) -> Result<EncodedQuad<Self::StrId>, Self::Error> { ) -> Result<EncodedQuad, Self::Error> {
Ok(EncodedQuad { Ok(EncodedQuad {
subject: self.encode_rio_named_or_blank_node(triple.subject, bnodes_map)?, subject: self.encode_rio_named_or_blank_node(triple.subject, bnodes_map)?,
predicate: self.encode_rio_named_node(triple.predicate)?, predicate: self.encode_rio_named_node(triple.predicate)?,
@ -1116,16 +1003,16 @@ pub(crate) trait WriteEncoder: StrEncodingAware {
}) })
} }
fn encode_str(&mut self, value: &str) -> Result<Self::StrId, Self::Error>; fn encode_str(&mut self, value: &str) -> Result<StrHash, Self::Error>;
} }
impl<S: StrContainer> WriteEncoder for S { impl<S: StrContainer> WriteEncoder for S {
fn encode_str(&mut self, value: &str) -> Result<Self::StrId, Self::Error> { fn encode_str(&mut self, value: &str) -> Result<StrHash, Self::Error> {
self.insert_str(value) self.insert_str(value)
} }
} }
pub fn parse_boolean_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_boolean_str(value: &str) -> Option<EncodedTerm> {
match value { match value {
"true" | "1" => Some(EncodedTerm::BooleanLiteral(true)), "true" | "1" => Some(EncodedTerm::BooleanLiteral(true)),
"false" | "0" => Some(EncodedTerm::BooleanLiteral(false)), "false" | "0" => Some(EncodedTerm::BooleanLiteral(false)),
@ -1133,78 +1020,75 @@ pub fn parse_boolean_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
} }
} }
pub fn parse_float_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_float_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::FloatLiteral).ok() value.parse().map(EncodedTerm::FloatLiteral).ok()
} }
pub fn parse_double_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_double_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::DoubleLiteral).ok() value.parse().map(EncodedTerm::DoubleLiteral).ok()
} }
pub fn parse_integer_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_integer_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::IntegerLiteral).ok() value.parse().map(EncodedTerm::IntegerLiteral).ok()
} }
pub fn parse_decimal_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_decimal_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::DecimalLiteral).ok() value.parse().map(EncodedTerm::DecimalLiteral).ok()
} }
pub fn parse_date_time_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_date_time_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::DateTimeLiteral).ok() value.parse().map(EncodedTerm::DateTimeLiteral).ok()
} }
pub fn parse_time_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_time_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::TimeLiteral).ok() value.parse().map(EncodedTerm::TimeLiteral).ok()
} }
pub fn parse_date_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_date_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::DateLiteral).ok() value.parse().map(EncodedTerm::DateLiteral).ok()
} }
pub fn parse_g_year_month_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_g_year_month_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::GYearMonthLiteral).ok() value.parse().map(EncodedTerm::GYearMonthLiteral).ok()
} }
pub fn parse_g_year_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_g_year_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::GYearLiteral).ok() value.parse().map(EncodedTerm::GYearLiteral).ok()
} }
pub fn parse_g_month_day_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_g_month_day_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::GMonthDayLiteral).ok() value.parse().map(EncodedTerm::GMonthDayLiteral).ok()
} }
pub fn parse_g_day_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_g_day_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::GDayLiteral).ok() value.parse().map(EncodedTerm::GDayLiteral).ok()
} }
pub fn parse_g_month_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_g_month_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::GMonthLiteral).ok() value.parse().map(EncodedTerm::GMonthLiteral).ok()
} }
pub fn parse_duration_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_duration_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::DurationLiteral).ok() value.parse().map(EncodedTerm::DurationLiteral).ok()
} }
pub fn parse_year_month_duration_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_year_month_duration_str(value: &str) -> Option<EncodedTerm> {
value value
.parse() .parse()
.map(EncodedTerm::YearMonthDurationLiteral) .map(EncodedTerm::YearMonthDurationLiteral)
.ok() .ok()
} }
pub fn parse_day_time_duration_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_day_time_duration_str(value: &str) -> Option<EncodedTerm> {
value.parse().map(EncodedTerm::DayTimeDurationLiteral).ok() value.parse().map(EncodedTerm::DayTimeDurationLiteral).ok()
} }
pub(crate) trait Decoder: StrLookup { pub(crate) trait Decoder: StrLookup {
fn decode_term( fn decode_term(&self, encoded: EncodedTerm) -> Result<Term, DecoderError<Self::Error>>;
&self,
encoded: EncodedTerm<Self::StrId>,
) -> Result<Term, DecoderError<Self::Error>>;
fn decode_named_or_blank_node( fn decode_named_or_blank_node(
&self, &self,
encoded: EncodedTerm<Self::StrId>, encoded: EncodedTerm,
) -> Result<NamedOrBlankNode, DecoderError<Self::Error>> { ) -> Result<NamedOrBlankNode, DecoderError<Self::Error>> {
match self.decode_term(encoded)? { match self.decode_term(encoded)? {
Term::NamedNode(named_node) => Ok(named_node.into()), Term::NamedNode(named_node) => Ok(named_node.into()),
@ -1217,7 +1101,7 @@ pub(crate) trait Decoder: StrLookup {
fn decode_named_node( fn decode_named_node(
&self, &self,
encoded: EncodedTerm<Self::StrId>, encoded: EncodedTerm,
) -> Result<NamedNode, DecoderError<Self::Error>> { ) -> Result<NamedNode, DecoderError<Self::Error>> {
match self.decode_term(encoded)? { match self.decode_term(encoded)? {
Term::NamedNode(named_node) => Ok(named_node), Term::NamedNode(named_node) => Ok(named_node),
@ -1230,10 +1114,7 @@ pub(crate) trait Decoder: StrLookup {
} }
} }
fn decode_triple( fn decode_triple(&self, encoded: &EncodedQuad) -> Result<Triple, DecoderError<Self::Error>> {
&self,
encoded: &EncodedQuad<Self::StrId>,
) -> Result<Triple, DecoderError<Self::Error>> {
Ok(Triple::new( Ok(Triple::new(
self.decode_named_or_blank_node(encoded.subject)?, self.decode_named_or_blank_node(encoded.subject)?,
self.decode_named_node(encoded.predicate)?, self.decode_named_node(encoded.predicate)?,
@ -1241,10 +1122,7 @@ pub(crate) trait Decoder: StrLookup {
)) ))
} }
fn decode_quad( fn decode_quad(&self, encoded: &EncodedQuad) -> Result<Quad, DecoderError<Self::Error>> {
&self,
encoded: &EncodedQuad<Self::StrId>,
) -> Result<Quad, DecoderError<Self::Error>> {
Ok(Quad::new( Ok(Quad::new(
self.decode_named_or_blank_node(encoded.subject)?, self.decode_named_or_blank_node(encoded.subject)?,
self.decode_named_node(encoded.predicate)?, self.decode_named_node(encoded.predicate)?,
@ -1258,10 +1136,7 @@ pub(crate) trait Decoder: StrLookup {
} }
impl<S: StrLookup> Decoder for S { impl<S: StrLookup> Decoder for S {
fn decode_term( fn decode_term(&self, encoded: EncodedTerm) -> Result<Term, DecoderError<Self::Error>> {
&self,
encoded: EncodedTerm<Self::StrId>,
) -> Result<Term, DecoderError<Self::Error>> {
match encoded { match encoded {
EncodedTerm::DefaultGraph => Err(DecoderError::Decoder { EncodedTerm::DefaultGraph => Err(DecoderError::Decoder {
msg: "The default graph tag is not a valid term".to_owned(), msg: "The default graph tag is not a valid term".to_owned(),
@ -1340,7 +1215,7 @@ impl<S: StrLookup> Decoder for S {
fn get_required_str<L: StrLookup>( fn get_required_str<L: StrLookup>(
lookup: &L, lookup: &L,
id: L::StrId, id: StrHash,
) -> Result<String, DecoderError<L::Error>> { ) -> Result<String, DecoderError<L::Error>> {
lookup lookup
.get_str(id) .get_str(id)

@ -76,8 +76,8 @@ pub struct SledStore {
graphs: Tree, graphs: Tree,
} }
type EncodedTerm = crate::store::numeric_encoder::EncodedTerm<StrHash>; type EncodedTerm = crate::store::numeric_encoder::EncodedTerm;
type EncodedQuad = crate::store::numeric_encoder::EncodedQuad<StrHash>; type EncodedQuad = crate::store::numeric_encoder::EncodedQuad;
//TODO: indexes for the default graph and indexes for the named graphs (no more Optional and space saving) //TODO: indexes for the default graph and indexes for the named graphs (no more Optional and space saving)
@ -902,7 +902,6 @@ impl fmt::Display for SledStore {
impl StrEncodingAware for SledStore { impl StrEncodingAware for SledStore {
type Error = io::Error; type Error = io::Error;
type StrId = StrHash;
} }
impl StrLookup for SledStore { impl StrLookup for SledStore {
@ -1280,7 +1279,6 @@ impl SledTransaction<'_> {
impl<'a> StrEncodingAware for &'a SledTransaction<'a> { impl<'a> StrEncodingAware for &'a SledTransaction<'a> {
type Error = SledUnabortableTransactionError; type Error = SledUnabortableTransactionError;
type StrId = StrHash;
} }
impl<'a> StrLookup for &'a SledTransaction<'a> { impl<'a> StrLookup for &'a SledTransaction<'a> {

Loading…
Cancel
Save