Introduces ReadableEncodedStore

pull/35/head
Tpt 4 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::plan::*;
use crate::sparql::ServiceHandler; use crate::sparql::ServiceHandler;
use crate::store::numeric_encoder::*; use crate::store::numeric_encoder::*;
use crate::store::StoreConnection; use crate::store::ReadableEncodedStore;
use crate::Error; use crate::Error;
use crate::Result; use crate::Result;
use digest::Digest; 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>; type EncodedTuplesIterator<'a> = Box<dyn Iterator<Item = Result<EncodedTuple>> + 'a>;
pub struct SimpleEvaluator<S: StoreConnection> { pub struct SimpleEvaluator<S: ReadableEncodedStore> {
dataset: DatasetView<S>, dataset: DatasetView<S>,
base_iri: Option<Iri<String>>, base_iri: Option<Iri<String>>,
bnodes_map: Mutex<BTreeMap<StrHash, u128>>, bnodes_map: Mutex<BTreeMap<StrHash, u128>>,
@ -39,7 +39,7 @@ pub struct SimpleEvaluator<S: StoreConnection> {
service_handler: Box<dyn ServiceHandler>, service_handler: Box<dyn ServiceHandler>,
} }
impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> { impl<'a, S: ReadableEncodedStore + 'a> SimpleEvaluator<S> {
pub fn new( pub fn new(
dataset: DatasetView<S>, dataset: DatasetView<S>,
base_iri: Option<Iri<String>>, 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>, eval: &'a SimpleEvaluator<S>,
right_plan: &'a PlanNode, right_plan: &'a PlanNode,
left_iter: EncodedTuplesIterator<'a>, left_iter: EncodedTuplesIterator<'a>,
current_right: 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>; type Item = Result<EncodedTuple>;
fn next(&mut self) -> Option<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>, eval: &'a SimpleEvaluator<S>,
right_plan: &'a PlanNode, right_plan: &'a PlanNode,
left_iter: EncodedTuplesIterator<'a>, left_iter: EncodedTuplesIterator<'a>,
@ -2081,7 +2081,7 @@ struct BadLeftJoinIterator<'a, S: StoreConnection> {
problem_vars: &'a [usize], 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>; type Item = Result<EncodedTuple>;
fn next(&mut self) -> Option<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>, eval: &'a SimpleEvaluator<S>,
plans: &'a [PlanNode], plans: &'a [PlanNode],
input: EncodedTuple, input: EncodedTuple,
@ -2132,7 +2132,7 @@ struct UnionIterator<'a, S: StoreConnection> {
current_plan: usize, 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>; type Item = Result<EncodedTuple>;
fn next(&mut self) -> Option<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>, eval: &'a SimpleEvaluator<S>,
iter: EncodedTuplesIterator<'a>, iter: EncodedTuplesIterator<'a>,
template: &'a [TripleTemplate], template: &'a [TripleTemplate],
@ -2159,7 +2159,7 @@ struct ConstructIterator<'a, S: StoreConnection> {
bnodes: Vec<BlankNode>, 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>; type Item = Result<Triple>;
fn next(&mut self) -> Option<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>, eval: &'a SimpleEvaluator<S>,
iter: EncodedTuplesIterator<'a>, iter: EncodedTuplesIterator<'a>,
quads: Box<dyn Iterator<Item = Result<EncodedQuad>> + '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>; type Item = Result<Triple>;
fn next(&mut self) -> Option<Result<Triple>> { fn next(&mut self) -> Option<Result<Triple>> {
@ -2517,18 +2517,18 @@ impl Accumulator for AvgAccumulator {
} }
#[allow(clippy::option_option)] #[allow(clippy::option_option)]
struct MinAccumulator<'a, S: StoreConnection> { struct MinAccumulator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>, eval: &'a SimpleEvaluator<S>,
min: Option<Option<EncodedTerm>>, 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 { fn new(eval: &'a SimpleEvaluator<S>) -> Self {
Self { eval, min: None } 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>) { 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 {
@ -2545,18 +2545,18 @@ impl<'a, S: StoreConnection + 'a> Accumulator for MinAccumulator<'a, S> {
} }
#[allow(clippy::option_option)] #[allow(clippy::option_option)]
struct MaxAccumulator<'a, S: StoreConnection> { struct MaxAccumulator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>, eval: &'a SimpleEvaluator<S>,
max: Option<Option<EncodedTerm>>, 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 { fn new(eval: &'a SimpleEvaluator<S>) -> Self {
Self { eval, max: None } 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>) { 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 {
@ -2590,14 +2590,14 @@ impl Accumulator for SampleAccumulator {
} }
#[allow(clippy::option_option)] #[allow(clippy::option_option)]
struct GroupConcatAccumulator<'a, S: StoreConnection> { struct GroupConcatAccumulator<'a, S: ReadableEncodedStore> {
eval: &'a SimpleEvaluator<S>, eval: &'a SimpleEvaluator<S>,
concat: Option<String>, concat: Option<String>,
language: Option<Option<StrHash>>, language: Option<Option<StrHash>>,
separator: &'a str, 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 { fn new(eval: &'a SimpleEvaluator<S>, separator: &'a str) -> Self {
Self { Self {
eval, 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>) { fn add(&mut self, element: Option<EncodedTerm>) {
if let Some(concat) = self.concat.as_mut() { if let Some(concat) = self.concat.as_mut() {
let element = if let Some(element) = element { 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::TripleTemplate;
use crate::sparql::plan::{DatasetView, PlanNode}; use crate::sparql::plan::{DatasetView, PlanNode};
use crate::sparql::plan_builder::PlanBuilder; use crate::sparql::plan_builder::PlanBuilder;
use crate::store::StoreConnection; use crate::store::ReadableEncodedStore;
use crate::Error; use crate::Error;
use crate::Result; use crate::Result;
use oxiri::Iri; use oxiri::Iri;
@ -35,9 +35,9 @@ pub trait PreparedQuery {
} }
/// An implementation of `PreparedQuery` for internal use /// 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 { Select {
plan: PlanNode, plan: PlanNode,
variables: Vec<Variable>, 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> { pub(crate) fn new(connection: S, query: &str, options: QueryOptions<'_>) -> Result<Self> {
let dataset = DatasetView::new(connection, options.default_graph_as_union); let dataset = DatasetView::new(connection, options.default_graph_as_union);
Ok(Self(match read_sparql_query(query, options.base_iri)? { 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<'_>> { fn exec(&self) -> Result<QueryResult<'_>> {
match &self.0 { match &self.0 {
SimplePreparedQueryAction::Select { SimplePreparedQueryAction::Select {

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

@ -58,6 +58,28 @@ pub trait StoreTransaction: StrContainer + Sized {
fn commit(self) -> Result<()>; 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` /// A `RepositoryConnection` from a `StoreConnection`
#[derive(Clone)] #[derive(Clone)]
pub struct StoreRepositoryConnection<S: StoreConnection> { pub struct StoreRepositoryConnection<S: StoreConnection> {

Loading…
Cancel
Save