Simplifies MemoryStore.quads_for_pattern signature

pull/35/head
Tpt 4 years ago
parent 480d3a0077
commit fa2d6c412f
  1. 2
      lib/benches/sparql_query.rs
  2. 333
      lib/src/store/memory.rs

@ -79,7 +79,7 @@ fn read_file_to_string(url: &str) -> Result<String> {
} }
fn load_graph(url: &str) -> Result<SimpleGraph> { fn load_graph(url: &str) -> Result<SimpleGraph> {
let mut store = MemoryStore::default(); let store = MemoryStore::default();
load_graph_to_store(url, &store, None)?; load_graph_to_store(url, &store, None)?;
Ok(store Ok(store
.quads_for_pattern(None, None, None, Some(None)) .quads_for_pattern(None, None, None, Some(None))

@ -6,7 +6,6 @@ use crate::{DatasetSyntax, GraphSyntax, Result};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::hash::Hash; use std::hash::Hash;
use std::io::BufRead; use std::io::BufRead;
use std::iter::{empty, once};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
/// Memory based store. /// Memory based store.
@ -132,24 +131,21 @@ impl MemoryStore {
/// # Result::Ok(()) /// # Result::Ok(())
/// ``` /// ```
#[allow(clippy::option_option)] #[allow(clippy::option_option)]
pub fn quads_for_pattern<'a>( pub fn quads_for_pattern(
&'a self, &self,
subject: Option<&NamedOrBlankNode>, subject: Option<&NamedOrBlankNode>,
predicate: Option<&NamedNode>, predicate: Option<&NamedNode>,
object: Option<&Term>, object: Option<&Term>,
graph_name: Option<Option<&NamedOrBlankNode>>, graph_name: Option<Option<&NamedOrBlankNode>>,
) -> Box<dyn Iterator<Item = Result<Quad>> + 'a> ) -> impl Iterator<Item = Result<Quad>> {
where
Self: 'a,
{
let subject = subject.map(|s| s.into()); let subject = subject.map(|s| s.into());
let predicate = predicate.map(|p| p.into()); let predicate = predicate.map(|p| p.into());
let object = object.map(|o| o.into()); let object = object.map(|o| o.into());
let graph_name = graph_name.map(|g| g.map_or(ENCODED_DEFAULT_GRAPH, |g| g.into())); let graph_name = graph_name.map(|g| g.map_or(ENCODED_DEFAULT_GRAPH, |g| g.into()));
Box::new( let this = self.clone();
self.encoded_quads_for_pattern(subject, predicate, object, graph_name) self.encoded_quads_for_pattern_inner(subject, predicate, object, graph_name)
.map(move |quad| self.decode_quad(&quad?)), .into_iter()
) .map(move |quad| this.decode_quad(&quad))
} }
/// Checks if this store contains a given quad /// Checks if this store contains a given quad
@ -289,37 +285,104 @@ impl MemoryStore {
}) })
} }
fn encoded_quads<'a>(&'a self) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { fn encoded_quads_for_pattern_inner(
Ok(quad_map_flatten(&self.indexes().gspo) &self,
.map(|(g, s, p, o)| Ok(EncodedQuad::new(s, p, o, g))) subject: Option<EncodedTerm>,
.collect::<Vec<_>>() predicate: Option<EncodedTerm>,
.into_iter()) object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
) -> Vec<EncodedQuad> {
match subject {
Some(subject) => match predicate {
Some(predicate) => match object {
Some(object) => match graph_name {
Some(graph_name) => {
let quad = EncodedQuad::new(subject, predicate, object, graph_name);
if self.contains_encoded(&quad) {
vec![quad]
} else {
vec![]
}
}
None => self
.encoded_quads_for_subject_predicate_object(subject, predicate, object),
},
None => match graph_name {
Some(graph_name) => self.encoded_quads_for_subject_predicate_graph(
subject, predicate, graph_name,
),
None => self.encoded_quads_for_subject_predicate(subject, predicate),
},
},
None => match object {
Some(object) => match graph_name {
Some(graph_name) => {
self.encoded_quads_for_subject_object_graph(subject, object, graph_name)
}
None => self.encoded_quads_for_subject_object(subject, object),
},
None => match graph_name {
Some(graph_name) => {
self.encoded_quads_for_subject_graph(subject, graph_name)
}
None => self.encoded_quads_for_subject(subject),
},
},
},
None => match predicate {
Some(predicate) => match object {
Some(object) => match graph_name {
Some(graph_name) => self.encoded_quads_for_predicate_object_graph(
predicate, object, graph_name,
),
None => self.encoded_quads_for_predicate_object(predicate, object),
},
None => match graph_name {
Some(graph_name) => {
self.encoded_quads_for_predicate_graph(predicate, graph_name)
}
None => self.encoded_quads_for_predicate(predicate),
},
},
None => match object {
Some(object) => match graph_name {
Some(graph_name) => self.encoded_quads_for_object_graph(object, graph_name),
None => self.encoded_quads_for_object(object),
},
None => match graph_name {
Some(graph_name) => self.encoded_quads_for_graph(graph_name),
None => self.encoded_quads(),
},
},
},
}
}
fn encoded_quads(&self) -> Vec<EncodedQuad> {
quad_map_flatten(&self.indexes().gspo)
.map(|(g, s, p, o)| EncodedQuad::new(s, p, o, g))
.collect()
} }
fn encoded_quads_for_subject( fn encoded_quads_for_subject(&self, subject: EncodedTerm) -> Vec<EncodedQuad> {
&self, option_triple_map_flatten(self.indexes().spog.get(&subject))
subject: EncodedTerm, .map(|(p, o, g)| EncodedQuad::new(subject, p, o, g))
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { .collect()
Ok(option_triple_map_flatten(self.indexes().spog.get(&subject))
.map(|(p, o, g)| Ok(EncodedQuad::new(subject, p, o, g)))
.collect::<Vec<_>>()
.into_iter())
} }
fn encoded_quads_for_subject_predicate( fn encoded_quads_for_subject_predicate(
&self, &self,
subject: EncodedTerm, subject: EncodedTerm,
predicate: EncodedTerm, predicate: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_pair_map_flatten( option_pair_map_flatten(
self.indexes() self.indexes()
.spog .spog
.get(&subject) .get(&subject)
.and_then(|pog| pog.get(&predicate)), .and_then(|pog| pog.get(&predicate)),
) )
.map(|(o, g)| Ok(EncodedQuad::new(subject, predicate, o, g))) .map(|(o, g)| EncodedQuad::new(subject, predicate, o, g))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_subject_predicate_object( fn encoded_quads_for_subject_predicate_object(
@ -327,99 +390,79 @@ impl MemoryStore {
subject: EncodedTerm, subject: EncodedTerm,
predicate: EncodedTerm, predicate: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_set_flatten( option_set_flatten(
self.indexes() self.indexes()
.spog .spog
.get(&subject) .get(&subject)
.and_then(|pog| pog.get(&predicate)) .and_then(|pog| pog.get(&predicate))
.and_then(|og| og.get(&object)), .and_then(|og| og.get(&object)),
) )
.map(|g| Ok(EncodedQuad::new(subject, predicate, object, g))) .map(|g| EncodedQuad::new(subject, predicate, object, g))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_subject_object( fn encoded_quads_for_subject_object(
&self, &self,
subject: EncodedTerm, subject: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_pair_map_flatten( option_pair_map_flatten(
self.indexes() self.indexes()
.ospg .ospg
.get(&object) .get(&object)
.and_then(|spg| spg.get(&subject)), .and_then(|spg| spg.get(&subject)),
) )
.map(|(p, g)| Ok(EncodedQuad::new(subject, p, object, g))) .map(|(p, g)| EncodedQuad::new(subject, p, object, g))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_predicate( fn encoded_quads_for_predicate(&self, predicate: EncodedTerm) -> Vec<EncodedQuad> {
&self, option_triple_map_flatten(self.indexes().posg.get(&predicate))
predicate: EncodedTerm, .map(|(o, s, g)| EncodedQuad::new(s, predicate, o, g))
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { .collect()
Ok(
option_triple_map_flatten(self.indexes().posg.get(&predicate))
.map(|(o, s, g)| Ok(EncodedQuad::new(s, predicate, o, g)))
.collect::<Vec<_>>()
.into_iter(),
)
} }
fn encoded_quads_for_predicate_object( fn encoded_quads_for_predicate_object(
&self, &self,
predicate: EncodedTerm, predicate: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_pair_map_flatten( option_pair_map_flatten(
self.indexes() self.indexes()
.posg .posg
.get(&predicate) .get(&predicate)
.and_then(|osg| osg.get(&object)), .and_then(|osg| osg.get(&object)),
) )
.map(|(s, g)| Ok(EncodedQuad::new(s, predicate, object, g))) .map(|(s, g)| EncodedQuad::new(s, predicate, object, g))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_object( fn encoded_quads_for_object(&self, object: EncodedTerm) -> Vec<EncodedQuad> {
&self, option_triple_map_flatten(self.indexes().ospg.get(&object))
object: EncodedTerm, .map(|(s, p, g)| EncodedQuad::new(s, p, object, g))
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { .collect()
Ok(option_triple_map_flatten(self.indexes().ospg.get(&object))
.map(|(s, p, g)| Ok(EncodedQuad::new(s, p, object, g)))
.collect::<Vec<_>>()
.into_iter())
} }
fn encoded_quads_for_graph( fn encoded_quads_for_graph(&self, graph_name: EncodedTerm) -> Vec<EncodedQuad> {
&self, option_triple_map_flatten(self.indexes().gspo.get(&graph_name))
graph_name: EncodedTerm, .map(|(s, p, o)| EncodedQuad::new(s, p, o, graph_name))
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { .collect()
Ok(
option_triple_map_flatten(self.indexes().gspo.get(&graph_name))
.map(|(s, p, o)| Ok(EncodedQuad::new(s, p, o, graph_name)))
.collect::<Vec<_>>()
.into_iter(),
)
} }
fn encoded_quads_for_subject_graph( fn encoded_quads_for_subject_graph(
&self, &self,
subject: EncodedTerm, subject: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_pair_map_flatten( option_pair_map_flatten(
self.indexes() self.indexes()
.gspo .gspo
.get(&graph_name) .get(&graph_name)
.and_then(|spo| spo.get(&subject)), .and_then(|spo| spo.get(&subject)),
) )
.map(|(p, o)| Ok(EncodedQuad::new(subject, p, o, graph_name))) .map(|(p, o)| EncodedQuad::new(subject, p, o, graph_name))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_subject_predicate_graph( fn encoded_quads_for_subject_predicate_graph(
@ -427,17 +470,16 @@ impl MemoryStore {
subject: EncodedTerm, subject: EncodedTerm,
predicate: EncodedTerm, predicate: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_set_flatten( option_set_flatten(
self.indexes() self.indexes()
.gspo .gspo
.get(&graph_name) .get(&graph_name)
.and_then(|spo| spo.get(&subject)) .and_then(|spo| spo.get(&subject))
.and_then(|po| po.get(&predicate)), .and_then(|po| po.get(&predicate)),
) )
.map(|o| Ok(EncodedQuad::new(subject, predicate, o, graph_name))) .map(|o| EncodedQuad::new(subject, predicate, o, graph_name))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_subject_object_graph( fn encoded_quads_for_subject_object_graph(
@ -445,33 +487,31 @@ impl MemoryStore {
subject: EncodedTerm, subject: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_set_flatten( option_set_flatten(
self.indexes() self.indexes()
.gosp .gosp
.get(&graph_name) .get(&graph_name)
.and_then(|osp| osp.get(&object)) .and_then(|osp| osp.get(&object))
.and_then(|sp| sp.get(&subject)), .and_then(|sp| sp.get(&subject)),
) )
.map(|p| Ok(EncodedQuad::new(subject, p, object, graph_name))) .map(|p| EncodedQuad::new(subject, p, object, graph_name))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_predicate_graph( fn encoded_quads_for_predicate_graph(
&self, &self,
predicate: EncodedTerm, predicate: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_pair_map_flatten( option_pair_map_flatten(
self.indexes() self.indexes()
.gpos .gpos
.get(&graph_name) .get(&graph_name)
.and_then(|pos| pos.get(&predicate)), .and_then(|pos| pos.get(&predicate)),
) )
.map(|(o, s)| Ok(EncodedQuad::new(s, predicate, o, graph_name))) .map(|(o, s)| EncodedQuad::new(s, predicate, o, graph_name))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_predicate_object_graph( fn encoded_quads_for_predicate_object_graph(
@ -479,33 +519,31 @@ impl MemoryStore {
predicate: EncodedTerm, predicate: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_set_flatten( option_set_flatten(
self.indexes() self.indexes()
.gpos .gpos
.get(&graph_name) .get(&graph_name)
.and_then(|pos| pos.get(&predicate)) .and_then(|pos| pos.get(&predicate))
.and_then(|os| os.get(&object)), .and_then(|os| os.get(&object)),
) )
.map(|s| Ok(EncodedQuad::new(s, predicate, object, graph_name))) .map(|s| EncodedQuad::new(s, predicate, object, graph_name))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
fn encoded_quads_for_object_graph( fn encoded_quads_for_object_graph(
&self, &self,
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>>> { ) -> Vec<EncodedQuad> {
Ok(option_pair_map_flatten( option_pair_map_flatten(
self.indexes() self.indexes()
.gosp .gosp
.get(&graph_name) .get(&graph_name)
.and_then(|osp| osp.get(&object)), .and_then(|osp| osp.get(&object)),
) )
.map(|(s, p)| Ok(EncodedQuad::new(s, p, object, graph_name))) .map(|(s, p)| EncodedQuad::new(s, p, object, graph_name))
.collect::<Vec<_>>() .collect()
.into_iter())
} }
} }
@ -550,83 +588,11 @@ impl<'a> ReadableEncodedStore for MemoryStore {
object: Option<EncodedTerm>, object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>, graph_name: Option<EncodedTerm>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'b> { ) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'b> {
match subject { Box::new(
Some(subject) => match predicate { self.encoded_quads_for_pattern_inner(subject, predicate, object, graph_name)
Some(predicate) => match object { .into_iter()
Some(object) => match graph_name { .map(Ok),
Some(graph_name) => { )
let quad = EncodedQuad::new(subject, predicate, object, graph_name);
if self.contains_encoded(&quad) {
Box::new(once(Ok(quad)))
} else {
Box::new(empty())
}
}
None => wrap_error(self.encoded_quads_for_subject_predicate_object(
subject, predicate, object,
)),
},
None => match graph_name {
Some(graph_name) => {
wrap_error(self.encoded_quads_for_subject_predicate_graph(
subject, predicate, graph_name,
))
}
None => {
wrap_error(self.encoded_quads_for_subject_predicate(subject, predicate))
}
},
},
None => match object {
Some(object) => match graph_name {
Some(graph_name) => {
wrap_error(self.encoded_quads_for_subject_object_graph(
subject, object, graph_name,
))
}
None => wrap_error(self.encoded_quads_for_subject_object(subject, object)),
},
None => match graph_name {
Some(graph_name) => {
wrap_error(self.encoded_quads_for_subject_graph(subject, graph_name))
}
None => wrap_error(self.encoded_quads_for_subject(subject)),
},
},
},
None => match predicate {
Some(predicate) => match object {
Some(object) => match graph_name {
Some(graph_name) => {
wrap_error(self.encoded_quads_for_predicate_object_graph(
predicate, object, graph_name,
))
}
None => {
wrap_error(self.encoded_quads_for_predicate_object(predicate, object))
}
},
None => match graph_name {
Some(graph_name) => wrap_error(
self.encoded_quads_for_predicate_graph(predicate, graph_name),
),
None => wrap_error(self.encoded_quads_for_predicate(predicate)),
},
},
None => match object {
Some(object) => match graph_name {
Some(graph_name) => {
wrap_error(self.encoded_quads_for_object_graph(object, graph_name))
}
None => wrap_error(self.encoded_quads_for_object(object)),
},
None => match graph_name {
Some(graph_name) => wrap_error(self.encoded_quads_for_graph(graph_name)),
None => wrap_error(self.encoded_quads()),
},
},
},
}
} }
} }
@ -744,15 +710,6 @@ impl WritableEncodedStore for MemoryStoreIndexes {
} }
} }
fn wrap_error<'a, E: 'static, I: Iterator<Item = Result<E>> + 'a>(
iter: Result<I>,
) -> Box<dyn Iterator<Item = Result<E>> + 'a> {
match iter {
Ok(iter) => Box::new(iter),
Err(error) => Box::new(once(Err(error))),
}
}
fn insert_into_quad_map<T: Eq + Hash>(map: &mut QuadMap<T>, e1: T, e2: T, e3: T, e4: T) { fn insert_into_quad_map<T: Eq + Hash>(map: &mut QuadMap<T>, e1: T, e2: T, e3: T, e4: T) {
map.entry(e1) map.entry(e1)
.or_default() .or_default()

Loading…
Cancel
Save