Adds explicit types for store quad iterators

pull/51/head
Tpt 4 years ago
parent cf67bda446
commit 4f3a5ad116
  1. 1
      CHANGELOG.md
  2. 62
      lib/src/store/memory.rs
  3. 49
      lib/src/store/rocksdb.rs
  4. 49
      lib/src/store/sled.rs
  5. 10
      python/src/memory_store.rs
  6. 11
      python/src/sled_store.rs

@ -5,6 +5,7 @@
- `QueryOptions::with_named_graph` now takes an `impl Into<NamedOrBlankNode>` instead of an `impl Into<NamedNode>`.
- `pyoxigraph` `query` methods now takes two new parameters, `default_graph` and `named_graphs`. `default_graph_uris` and `named_graph_uris` parameters are deprecated.
- Fixes a bug in `xsd:gYear` parsing.
- Adds explicit types for quads iterators returned by stores.
## [0.1.0] - 2020-08-09

@ -175,7 +175,7 @@ impl MemoryStore {
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> impl Iterator<Item = Quad> {
) -> MemoryQuadIter {
let quads = if let Some((subject, predicate, object, graph_name)) =
get_encoded_quad_pattern(self, subject, predicate, object, graph_name)
.unwrap_infallible()
@ -184,10 +184,18 @@ impl MemoryStore {
} else {
Vec::new()
};
let this = self.clone();
quads.into_iter().map(
move |quad| this.decode_quad(&quad).unwrap(), // Could not fail
)
MemoryQuadIter {
iter: quads.into_iter(),
store: self.clone(),
}
}
/// Returns all the quads contained in the store
pub fn iter(&self) -> MemoryQuadIter {
MemoryQuadIter {
iter: self.encoded_quads().into_iter(),
store: self.clone(),
}
}
/// Checks if this store contains a given quad
@ -424,11 +432,7 @@ impl MemoryStore {
/// # std::io::Result::Ok(())
/// ```
pub fn dump_dataset(&self, writer: impl Write, format: DatasetFormat) -> Result<(), io::Error> {
dump_dataset(
self.quads_for_pattern(None, None, None, None).map(Ok),
writer,
format,
)
dump_dataset(self.iter().map(Ok), writer, format)
}
#[allow(clippy::expect_used)]
@ -1222,9 +1226,27 @@ impl Extend<Quad> for MemoryStore {
}
}
impl IntoIterator for MemoryStore {
type Item = Quad;
type IntoIter = MemoryQuadIter;
fn into_iter(self) -> MemoryQuadIter {
self.iter()
}
}
impl<'a> IntoIterator for &'a MemoryStore {
type Item = Quad;
type IntoIter = MemoryQuadIter;
fn into_iter(self) -> MemoryQuadIter {
self.iter()
}
}
impl fmt::Display for MemoryStore {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for t in self.quads_for_pattern(None, None, None, None) {
for t in self {
writeln!(f, "{}", t)?;
}
Ok(())
@ -1254,6 +1276,24 @@ impl Iterator for EncodedQuadsIter {
}
}
/// An iterator returning the quads contained in a [`MemoryStore`](struct.MemoryStore.html).
pub struct MemoryQuadIter {
iter: IntoIter<EncodedQuad>,
store: MemoryStore,
}
impl Iterator for MemoryQuadIter {
type Item = Quad;
fn next(&mut self) -> Option<Quad> {
Some(self.store.decode_quad(&self.iter.next()?).unwrap())
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl StrId for LargeSpur {}
// Isomorphism implementation

@ -155,15 +155,22 @@ impl RocksDbStore {
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> impl Iterator<Item = Result<Quad, io::Error>> {
match get_encoded_quad_pattern(self, subject, predicate, object, graph_name) {
Ok(Some((subject, predicate, object, graph_name))) => QuadsIter::Quads {
) -> RocksDbQuadIter {
RocksDbQuadIter {
inner: match get_encoded_quad_pattern(self, subject, predicate, object, graph_name) {
Ok(Some((subject, predicate, object, graph_name))) => QuadIterInner::Quads {
iter: self.encoded_quads_for_pattern(subject, predicate, object, graph_name),
store: self.clone(),
},
Ok(None) => QuadsIter::Empty,
Err(error) => QuadsIter::Error(once(error)),
Ok(None) => QuadIterInner::Empty,
Err(error) => QuadIterInner::Error(once(error)),
},
}
}
/// Returns all the quads contained in the store
pub fn iter(&self) -> RocksDbQuadIter {
self.quads_for_pattern(None, None, None, None)
}
/// Checks if this store contains a given quad
@ -318,11 +325,7 @@ impl RocksDbStore {
///
/// See [`MemoryStore`](../memory/struct.MemoryStore.html#method.dump_dataset) for a usage example.
pub fn dump_dataset(&self, writer: impl Write, syntax: DatasetFormat) -> Result<(), io::Error> {
dump_dataset(
self.quads_for_pattern(None, None, None, None),
writer,
syntax,
)
dump_dataset(self.iter(), writer, syntax)
}
fn id2str_cf(&self) -> &ColumnFamily {
@ -617,7 +620,7 @@ impl RocksDbStore {
impl fmt::Display for RocksDbStore {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for t in self.quads_for_pattern(None, None, None, None) {
for t in self.iter() {
writeln!(f, "{}", t.map_err(|_| fmt::Error)?)?;
}
Ok(())
@ -1161,7 +1164,12 @@ fn map_err(e: Error) -> io::Error {
io::Error::new(io::ErrorKind::Other, e)
}
enum QuadsIter {
/// An iterator returning the quads contained in a [`RocksDbStore`](struct.RocksDbStore.html).
pub struct RocksDbQuadIter {
inner: QuadIterInner,
}
enum QuadIterInner {
Quads {
iter: DecodingIndexesIterator,
store: RocksDbStore,
@ -1170,17 +1178,17 @@ enum QuadsIter {
Empty,
}
impl Iterator for QuadsIter {
impl Iterator for RocksDbQuadIter {
type Item = Result<Quad, io::Error>;
fn next(&mut self) -> Option<Result<Quad, io::Error>> {
match self {
Self::Quads { iter, store } => Some(match iter.next()? {
match &mut self.inner {
QuadIterInner::Quads { iter, store } => Some(match iter.next()? {
Ok(quad) => store.decode_quad(&quad).map_err(|e| e.into()),
Err(error) => Err(error),
}),
Self::Error(iter) => iter.next().map(Err),
Self::Empty => None,
QuadIterInner::Error(iter) => iter.next().map(Err),
QuadIterInner::Empty => None,
}
}
}
@ -1242,12 +1250,7 @@ fn store() -> Result<(), io::Error> {
})?;
assert_eq!(store.len(), 4);
assert_eq!(
store
.quads_for_pattern(None, None, None, None)
.collect::<Result<Vec<_>, _>>()?,
all_quads
);
assert_eq!(store.iter().collect::<Result<Vec<_>, _>>()?, all_quads);
assert_eq!(
store
.quads_for_pattern(Some(main_s.as_ref()), None, None, None)

@ -164,15 +164,22 @@ impl SledStore {
predicate: Option<NamedNodeRef<'_>>,
object: Option<TermRef<'_>>,
graph_name: Option<GraphNameRef<'_>>,
) -> impl Iterator<Item = Result<Quad, io::Error>> {
match get_encoded_quad_pattern(self, subject, predicate, object, graph_name) {
Ok(Some((subject, predicate, object, graph_name))) => QuadsIter::Quads {
) -> SledQuadIter {
SledQuadIter {
inner: match get_encoded_quad_pattern(self, subject, predicate, object, graph_name) {
Ok(Some((subject, predicate, object, graph_name))) => QuadIterInner::Quads {
iter: self.encoded_quads_for_pattern(subject, predicate, object, graph_name),
store: self.clone(),
},
Ok(None) => QuadsIter::Empty,
Err(error) => QuadsIter::Error(once(error)),
Ok(None) => QuadIterInner::Empty,
Err(error) => QuadIterInner::Error(once(error)),
},
}
}
/// Returns all the quads contained in the store
pub fn iter(&self) -> SledQuadIter {
self.quads_for_pattern(None, None, None, None)
}
/// Checks if this store contains a given quad
@ -352,11 +359,7 @@ impl SledStore {
///
/// See [`MemoryStore`](../memory/struct.MemoryStore.html#method.dump_dataset) for a usage example.
pub fn dump_dataset(&self, writer: impl Write, format: DatasetFormat) -> Result<(), io::Error> {
dump_dataset(
self.quads_for_pattern(None, None, None, None),
writer,
format,
)
dump_dataset(self.iter(), writer, format)
}
fn contains_encoded(&self, quad: &EncodedQuad) -> Result<bool, io::Error> {
@ -590,7 +593,7 @@ impl SledStore {
impl fmt::Display for SledStore {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for t in self.quads_for_pattern(None, None, None, None) {
for t in self.iter() {
writeln!(f, "{}", t.map_err(|_| fmt::Error)?)?;
}
Ok(())
@ -1217,7 +1220,12 @@ impl Iterator for DecodingQuadIterator {
}
}
enum QuadsIter {
/// An iterator returning the quads contained in a [`SledStore`](struct.SledStore.html).
pub struct SledQuadIter {
inner: QuadIterInner,
}
enum QuadIterInner {
Quads {
iter: DecodingQuadsIterator,
store: SledStore,
@ -1226,17 +1234,17 @@ enum QuadsIter {
Empty,
}
impl Iterator for QuadsIter {
impl Iterator for SledQuadIter {
type Item = Result<Quad, io::Error>;
fn next(&mut self) -> Option<Result<Quad, io::Error>> {
match self {
Self::Quads { iter, store } => Some(match iter.next()? {
match &mut self.inner {
QuadIterInner::Quads { iter, store } => Some(match iter.next()? {
Ok(quad) => store.decode_quad(&quad).map_err(|e| e.into()),
Err(error) => Err(error),
}),
Self::Error(iter) => iter.next().map(Err),
Self::Empty => None,
QuadIterInner::Error(iter) => iter.next().map(Err),
QuadIterInner::Empty => None,
}
}
}
@ -1293,12 +1301,7 @@ fn store() -> Result<(), io::Error> {
result?;
assert_eq!(store.len(), 4);
assert_eq!(
store
.quads_for_pattern(None, None, None, None)
.collect::<Result<Vec<_>, _>>()?,
all_quads
);
assert_eq!(store.iter().collect::<Result<Vec<_>, _>>()?, all_quads);
assert_eq!(
store
.quads_for_pattern(Some(main_s.as_ref()), None, None, None)

@ -4,7 +4,7 @@ use crate::sparql::*;
use crate::store_utils::*;
use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::*;
use oxigraph::MemoryStore;
use oxigraph::store::memory::*;
use pyo3::basic::CompareOp;
use pyo3::exceptions::{NotImplementedError, ValueError};
use pyo3::prelude::*;
@ -95,12 +95,12 @@ impl PyMemoryStore {
let (subject, predicate, object, graph_name) =
extract_quads_pattern(subject, predicate, object, graph_name)?;
Ok(QuadIter {
inner: Box::new(self.inner.quads_for_pattern(
inner: self.inner.quads_for_pattern(
subject.as_ref().map(|t| t.into()),
predicate.as_ref().map(|t| t.into()),
object.as_ref().map(|t| t.into()),
graph_name.as_ref().map(|t| t.into()),
)),
),
})
}
@ -351,14 +351,14 @@ impl<'p> PySequenceProtocol<'p> for PyMemoryStore {
impl PyIterProtocol for PyMemoryStore {
fn __iter__(slf: PyRef<Self>) -> QuadIter {
QuadIter {
inner: Box::new(slf.inner.quads_for_pattern(None, None, None, None)),
inner: slf.inner.iter(),
}
}
}
#[pyclass(unsendable)]
pub struct QuadIter {
inner: Box<dyn Iterator<Item = Quad>>,
inner: MemoryQuadIter,
}
#[pyproto]

@ -4,11 +4,10 @@ use crate::sparql::*;
use crate::store_utils::*;
use oxigraph::io::{DatasetFormat, GraphFormat};
use oxigraph::model::*;
use oxigraph::SledStore;
use oxigraph::store::sled::*;
use pyo3::exceptions::ValueError;
use pyo3::prelude::*;
use pyo3::{PyIterProtocol, PyObjectProtocol, PySequenceProtocol};
use std::io;
use std::io::BufReader;
/// Store based on the `Sled <https://sled.rs/>`_ key-value database.
@ -110,12 +109,12 @@ impl PySledStore {
let (subject, predicate, object, graph_name) =
extract_quads_pattern(subject, predicate, object, graph_name)?;
Ok(QuadIter {
inner: Box::new(self.inner.quads_for_pattern(
inner: self.inner.quads_for_pattern(
subject.as_ref().map(|t| t.into()),
predicate.as_ref().map(|t| t.into()),
object.as_ref().map(|t| t.into()),
graph_name.as_ref().map(|t| t.into()),
)),
),
})
}
@ -360,14 +359,14 @@ impl PySequenceProtocol for PySledStore {
impl PyIterProtocol for PySledStore {
fn __iter__(slf: PyRef<Self>) -> QuadIter {
QuadIter {
inner: Box::new(slf.inner.quads_for_pattern(None, None, None, None)),
inner: slf.inner.iter(),
}
}
}
#[pyclass(unsendable)]
pub struct QuadIter {
inner: Box<dyn Iterator<Item = Result<Quad, io::Error>>>,
inner: SledQuadIter,
}
#[pyproto]

Loading…
Cancel
Save