Introduces ReadableEncodedStore

pull/35/head
Tpt 5 years ago
parent 6930a84521
commit 2d31de987a
  1. 44
      lib/src/sparql/eval.rs
  2. 10
      lib/src/sparql/mod.rs
  3. 18
      lib/src/sparql/plan.rs
  4. 22
      lib/src/store/mod.rs

@ -6,7 +6,7 @@ use crate::sparql::model::*;
use crate::sparql::plan::*;
use crate::sparql::ServiceHandler;
use crate::store::numeric_encoder::*;
use crate::store::StoreConnection;
use crate::store::ReadableEncodedStore;
use crate::Error;
use crate::Result;
use digest::Digest;
@ -31,7 +31,7 @@ const REGEX_SIZE_LIMIT: usize = 1_000_000;
type EncodedTuplesIterator<'a> = Box<dyn Iterator<Item = Result<EncodedTuple>> + 'a>;
pub struct SimpleEvaluator<S: StoreConnection> {
pub struct SimpleEvaluator<S: ReadableEncodedStore> {
dataset: DatasetView<S>,
base_iri: Option<Iri<String>>,
bnodes_map: Mutex<BTreeMap<StrHash, u128>>,
@ -39,7 +39,7 @@ pub struct SimpleEvaluator<S: StoreConnection> {
service_handler: Box<dyn ServiceHandler>,
}
impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
impl<'a, S: ReadableEncodedStore + 'a> SimpleEvaluator<S> {
pub fn new(
dataset: DatasetView<S>,
base_iri: Option<Iri<String>>,
@ -2044,14 +2044,14 @@ impl<'a> Iterator for AntiJoinIterator<'a> {
}
}
struct LeftJoinIterator<'a, S: StoreConnection> {
struct LeftJoinIterator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>,
right_plan: &'a PlanNode,
left_iter: EncodedTuplesIterator<'a>,
current_right: EncodedTuplesIterator<'a>,
}
impl<'a, S: StoreConnection> Iterator for LeftJoinIterator<'a, S> {
impl<'a, S: ReadableEncodedStore> Iterator for LeftJoinIterator<'a, S> {
type Item = Result<EncodedTuple>;
fn next(&mut self) -> Option<Result<EncodedTuple>> {
@ -2072,7 +2072,7 @@ impl<'a, S: StoreConnection> Iterator for LeftJoinIterator<'a, S> {
}
}
struct BadLeftJoinIterator<'a, S: StoreConnection> {
struct BadLeftJoinIterator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>,
right_plan: &'a PlanNode,
left_iter: EncodedTuplesIterator<'a>,
@ -2081,7 +2081,7 @@ struct BadLeftJoinIterator<'a, S: StoreConnection> {
problem_vars: &'a [usize],
}
impl<'a, S: StoreConnection> Iterator for BadLeftJoinIterator<'a, S> {
impl<'a, S: ReadableEncodedStore> Iterator for BadLeftJoinIterator<'a, S> {
type Item = Result<EncodedTuple>;
fn next(&mut self) -> Option<Result<EncodedTuple>> {
@ -2124,7 +2124,7 @@ impl<'a, S: StoreConnection> Iterator for BadLeftJoinIterator<'a, S> {
}
}
struct UnionIterator<'a, S: StoreConnection> {
struct UnionIterator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>,
plans: &'a [PlanNode],
input: EncodedTuple,
@ -2132,7 +2132,7 @@ struct UnionIterator<'a, S: StoreConnection> {
current_plan: usize,
}
impl<'a, S: StoreConnection> Iterator for UnionIterator<'a, S> {
impl<'a, S: ReadableEncodedStore> Iterator for UnionIterator<'a, S> {
type Item = Result<EncodedTuple>;
fn next(&mut self) -> Option<Result<EncodedTuple>> {
@ -2151,7 +2151,7 @@ impl<'a, S: StoreConnection> Iterator for UnionIterator<'a, S> {
}
}
struct ConstructIterator<'a, S: StoreConnection> {
struct ConstructIterator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>,
iter: EncodedTuplesIterator<'a>,
template: &'a [TripleTemplate],
@ -2159,7 +2159,7 @@ struct ConstructIterator<'a, S: StoreConnection> {
bnodes: Vec<BlankNode>,
}
impl<'a, S: StoreConnection + 'a> Iterator for ConstructIterator<'a, S> {
impl<'a, S: ReadableEncodedStore + 'a> Iterator for ConstructIterator<'a, S> {
type Item = Result<Triple>;
fn next(&mut self) -> Option<Result<Triple>> {
@ -2222,13 +2222,13 @@ fn decode_triple(
))
}
struct DescribeIterator<'a, S: StoreConnection> {
struct DescribeIterator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>,
iter: EncodedTuplesIterator<'a>,
quads: Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a>,
}
impl<'a, S: StoreConnection + 'a> Iterator for DescribeIterator<'a, S> {
impl<'a, S: ReadableEncodedStore + 'a> Iterator for DescribeIterator<'a, S> {
type Item = Result<Triple>;
fn next(&mut self) -> Option<Result<Triple>> {
@ -2517,18 +2517,18 @@ impl Accumulator for AvgAccumulator {
}
#[allow(clippy::option_option)]
struct MinAccumulator<'a, S: StoreConnection> {
struct MinAccumulator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>,
min: Option<Option<EncodedTerm>>,
}
impl<'a, S: StoreConnection + 'a> MinAccumulator<'a, S> {
impl<'a, S: ReadableEncodedStore + 'a> MinAccumulator<'a, S> {
fn new(eval: &'a SimpleEvaluator<S>) -> Self {
Self { eval, min: None }
}
}
impl<'a, S: StoreConnection + 'a> Accumulator for MinAccumulator<'a, S> {
impl<'a, S: ReadableEncodedStore + 'a> Accumulator for MinAccumulator<'a, S> {
fn add(&mut self, element: Option<EncodedTerm>) {
if let Some(min) = self.min {
if self.eval.cmp_terms(element, min) == Ordering::Less {
@ -2545,18 +2545,18 @@ impl<'a, S: StoreConnection + 'a> Accumulator for MinAccumulator<'a, S> {
}
#[allow(clippy::option_option)]
struct MaxAccumulator<'a, S: StoreConnection> {
struct MaxAccumulator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>,
max: Option<Option<EncodedTerm>>,
}
impl<'a, S: StoreConnection + 'a> MaxAccumulator<'a, S> {
impl<'a, S: ReadableEncodedStore + 'a> MaxAccumulator<'a, S> {
fn new(eval: &'a SimpleEvaluator<S>) -> Self {
Self { eval, max: None }
}
}
impl<'a, S: StoreConnection + 'a> Accumulator for MaxAccumulator<'a, S> {
impl<'a, S: ReadableEncodedStore + 'a> Accumulator for MaxAccumulator<'a, S> {
fn add(&mut self, element: Option<EncodedTerm>) {
if let Some(max) = self.max {
if self.eval.cmp_terms(element, max) == Ordering::Greater {
@ -2590,14 +2590,14 @@ impl Accumulator for SampleAccumulator {
}
#[allow(clippy::option_option)]
struct GroupConcatAccumulator<'a, S: StoreConnection> {
struct GroupConcatAccumulator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>,
concat: Option<String>,
language: Option<Option<StrHash>>,
separator: &'a str,
}
impl<'a, S: StoreConnection + 'a> GroupConcatAccumulator<'a, S> {
impl<'a, S: ReadableEncodedStore + 'a> GroupConcatAccumulator<'a, S> {
fn new(eval: &'a SimpleEvaluator<S>, separator: &'a str) -> Self {
Self {
eval,
@ -2608,7 +2608,7 @@ impl<'a, S: StoreConnection + 'a> GroupConcatAccumulator<'a, S> {
}
}
impl<'a, S: StoreConnection + 'a> Accumulator for GroupConcatAccumulator<'a, S> {
impl<'a, S: ReadableEncodedStore + 'a> Accumulator for GroupConcatAccumulator<'a, S> {
fn add(&mut self, element: Option<EncodedTerm>) {
if let Some(concat) = self.concat.as_mut() {
let element = if let Some(element) = element {

@ -16,7 +16,7 @@ use crate::sparql::parser::read_sparql_query;
use crate::sparql::plan::TripleTemplate;
use crate::sparql::plan::{DatasetView, PlanNode};
use crate::sparql::plan_builder::PlanBuilder;
use crate::store::StoreConnection;
use crate::store::ReadableEncodedStore;
use crate::Error;
use crate::Result;
use oxiri::Iri;
@ -35,9 +35,9 @@ pub trait PreparedQuery {
}
/// An implementation of `PreparedQuery` for internal use
pub struct SimplePreparedQuery<S: StoreConnection>(SimplePreparedQueryAction<S>);
pub struct SimplePreparedQuery<S: ReadableEncodedStore>(SimplePreparedQueryAction<S>);
enum SimplePreparedQueryAction<S: StoreConnection> {
enum SimplePreparedQueryAction<S: ReadableEncodedStore> {
Select {
plan: PlanNode,
variables: Vec<Variable>,
@ -58,7 +58,7 @@ enum SimplePreparedQueryAction<S: StoreConnection> {
},
}
impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
impl<'a, S: ReadableEncodedStore + 'a> SimplePreparedQuery<S> {
pub(crate) fn new(connection: S, query: &str, options: QueryOptions<'_>) -> Result<Self> {
let dataset = DatasetView::new(connection, options.default_graph_as_union);
Ok(Self(match read_sparql_query(query, options.base_iri)? {
@ -131,7 +131,7 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
}
}
impl<S: StoreConnection> PreparedQuery for SimplePreparedQuery<S> {
impl<S: ReadableEncodedStore> PreparedQuery for SimplePreparedQuery<S> {
fn exec(&self) -> Result<QueryResult<'_>> {
match &self.0 {
SimplePreparedQueryAction::Select {

@ -4,7 +4,7 @@ use crate::store::numeric_encoder::{
EncodedQuad, EncodedTerm, Encoder, MemoryStrStore, StrContainer, StrHash, StrLookup,
ENCODED_DEFAULT_GRAPH,
};
use crate::store::StoreConnection;
use crate::store::ReadableEncodedStore;
use crate::Result;
use std::cell::{RefCell, RefMut};
use std::collections::BTreeSet;
@ -553,13 +553,13 @@ impl EncodedTuple {
}
}
pub struct DatasetView<S: StoreConnection> {
pub struct DatasetView<S: ReadableEncodedStore> {
store: S,
extra: RefCell<MemoryStrStore>,
default_graph_as_union: bool,
}
impl<S: StoreConnection> DatasetView<S> {
impl<S: ReadableEncodedStore> DatasetView<S> {
pub fn new(store: S, default_graph_as_union: bool) -> Self {
Self {
store,
@ -578,7 +578,7 @@ impl<S: StoreConnection> DatasetView<S> {
if graph_name == None {
Box::new(
self.store
.quads_for_pattern(subject, predicate, object, None)
.encoded_quads_for_pattern(subject, predicate, object, None)
.filter(|quad| match quad {
Err(_) => true,
Ok(quad) => quad.graph_name != ENCODED_DEFAULT_GRAPH,
@ -587,7 +587,7 @@ impl<S: StoreConnection> DatasetView<S> {
} else if graph_name == Some(ENCODED_DEFAULT_GRAPH) && self.default_graph_as_union {
Box::new(
self.store
.quads_for_pattern(subject, predicate, object, None)
.encoded_quads_for_pattern(subject, predicate, object, None)
.map(|quad| {
let quad = quad?;
Ok(EncodedQuad::new(
@ -600,7 +600,7 @@ impl<S: StoreConnection> DatasetView<S> {
)
} else {
self.store
.quads_for_pattern(subject, predicate, object, graph_name)
.encoded_quads_for_pattern(subject, predicate, object, graph_name)
}
}
@ -612,7 +612,7 @@ impl<S: StoreConnection> DatasetView<S> {
}
}
impl<S: StoreConnection> StrLookup for DatasetView<S> {
impl<S: ReadableEncodedStore> StrLookup for DatasetView<S> {
fn get_str(&self, id: StrHash) -> Result<Option<String>> {
if let Some(value) = self.extra.borrow().get_str(id)? {
Ok(Some(value))
@ -622,12 +622,12 @@ impl<S: StoreConnection> StrLookup for DatasetView<S> {
}
}
struct DatasetViewStrContainer<'a, S: StoreConnection> {
struct DatasetViewStrContainer<'a, S: ReadableEncodedStore> {
store: &'a S,
extra: RefMut<'a, MemoryStrStore>,
}
impl<'a, S: StoreConnection> StrContainer for DatasetViewStrContainer<'a, S> {
impl<'a, S: ReadableEncodedStore> StrContainer for DatasetViewStrContainer<'a, S> {
fn insert_str(&mut self, key: StrHash, value: &str) -> Result<()> {
if self.store.get_str(key)?.is_none() {
self.extra.insert_str(key, value)

@ -58,6 +58,28 @@ pub trait StoreTransaction: StrContainer + Sized {
fn commit(self) -> Result<()>;
}
pub trait ReadableEncodedStore: StrLookup + Sized {
fn encoded_quads_for_pattern<'a>(
&'a self,
subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a>;
}
impl<S: StoreConnection> ReadableEncodedStore for S {
fn encoded_quads_for_pattern<'a>(
&'a self,
subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a> {
self.quads_for_pattern(subject, predicate, object, graph_name)
}
}
/// A `RepositoryConnection` from a `StoreConnection`
#[derive(Clone)]
pub struct StoreRepositoryConnection<S: StoreConnection> {

Loading…
Cancel
Save