Simplifies quads pattern in the RocksDB patterns

pull/22/head
Tpt 5 years ago
parent ceac3b879d
commit c477324845
  1. 252
      lib/src/store/rocksdb.rs

@ -246,17 +246,14 @@ impl<'a> StoreConnection for RocksDbStoreConnection<'a> {
impl<'a> RocksDbStoreConnection<'a> { impl<'a> RocksDbStoreConnection<'a> {
fn quads(&self) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { fn quads(&self) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.spog_quads(b"", EncodedQuadPattern::new(None, None, None, None)) self.spog_quads(Vec::default())
} }
fn quads_for_subject( fn quads_for_subject(
&self, &self,
subject: EncodedTerm, subject: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.spog_quads( self.spog_quads(encode_term(subject)?)
&encode_term(subject)?,
EncodedQuadPattern::new(Some(subject), None, None, None),
)
} }
fn quads_for_subject_predicate( fn quads_for_subject_predicate(
@ -264,10 +261,7 @@ impl<'a> RocksDbStoreConnection<'a> {
subject: EncodedTerm, subject: EncodedTerm,
predicate: EncodedTerm, predicate: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.spog_quads( self.spog_quads(encode_term_pair(subject, predicate)?)
&encode_term_pair(subject, predicate)?,
EncodedQuadPattern::new(Some(subject), Some(predicate), None, None),
)
} }
fn quads_for_subject_predicate_object( fn quads_for_subject_predicate_object(
@ -276,10 +270,7 @@ impl<'a> RocksDbStoreConnection<'a> {
predicate: EncodedTerm, predicate: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.spog_quads( self.spog_quads(encode_term_triple(subject, predicate, object)?)
&encode_term_triple(subject, predicate, object)?,
EncodedQuadPattern::new(Some(subject), Some(predicate), Some(object), None),
)
} }
fn quads_for_subject_object( fn quads_for_subject_object(
@ -287,20 +278,14 @@ impl<'a> RocksDbStoreConnection<'a> {
subject: EncodedTerm, subject: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.ospg_quads( self.ospg_quads(encode_term_pair(object, subject)?)
&encode_term_pair(object, subject)?,
EncodedQuadPattern::new(Some(subject), None, Some(object), None),
)
} }
fn quads_for_predicate( fn quads_for_predicate(
&self, &self,
predicate: EncodedTerm, predicate: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.posg_quads( self.posg_quads(encode_term(predicate)?)
&encode_term(predicate)?,
EncodedQuadPattern::new(None, Some(predicate), None, None),
)
} }
fn quads_for_predicate_object( fn quads_for_predicate_object(
@ -308,30 +293,21 @@ impl<'a> RocksDbStoreConnection<'a> {
predicate: EncodedTerm, predicate: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.posg_quads( self.posg_quads(encode_term_pair(predicate, object)?)
&encode_term_pair(predicate, object)?,
EncodedQuadPattern::new(None, Some(predicate), Some(object), None),
)
} }
fn quads_for_object( fn quads_for_object(
&self, &self,
object: EncodedTerm, object: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.ospg_quads( self.ospg_quads(encode_term(object)?)
&encode_term(object)?,
EncodedQuadPattern::new(None, None, Some(object), None),
)
} }
fn quads_for_graph( fn quads_for_graph(
&self, &self,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.gspo_quads( self.gspo_quads(encode_term(graph_name)?)
&encode_term(graph_name)?,
EncodedQuadPattern::new(None, None, None, Some(graph_name)),
)
} }
fn quads_for_subject_graph( fn quads_for_subject_graph(
@ -339,10 +315,7 @@ impl<'a> RocksDbStoreConnection<'a> {
subject: EncodedTerm, subject: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.gspo_quads( self.gspo_quads(encode_term_pair(graph_name, subject)?)
&encode_term_pair(graph_name, subject)?,
EncodedQuadPattern::new(Some(subject), None, None, Some(graph_name)),
)
} }
fn quads_for_subject_predicate_graph( fn quads_for_subject_predicate_graph(
@ -351,10 +324,7 @@ impl<'a> RocksDbStoreConnection<'a> {
predicate: EncodedTerm, predicate: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.gspo_quads( self.gspo_quads(encode_term_triple(graph_name, subject, predicate)?)
&encode_term_triple(graph_name, subject, predicate)?,
EncodedQuadPattern::new(Some(subject), Some(predicate), None, Some(graph_name)),
)
} }
fn quads_for_subject_object_graph( fn quads_for_subject_object_graph(
@ -363,10 +333,7 @@ impl<'a> RocksDbStoreConnection<'a> {
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.gosp_quads( self.gosp_quads(encode_term_triple(graph_name, object, subject)?)
&encode_term_triple(graph_name, object, subject)?,
EncodedQuadPattern::new(Some(subject), None, Some(object), Some(graph_name)),
)
} }
fn quads_for_predicate_graph( fn quads_for_predicate_graph(
@ -374,10 +341,7 @@ impl<'a> RocksDbStoreConnection<'a> {
predicate: EncodedTerm, predicate: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.gpos_quads( self.gpos_quads(encode_term_pair(graph_name, predicate)?)
&encode_term_pair(graph_name, predicate)?,
EncodedQuadPattern::new(None, Some(predicate), None, Some(graph_name)),
)
} }
fn quads_for_predicate_object_graph( fn quads_for_predicate_object_graph(
@ -386,10 +350,7 @@ impl<'a> RocksDbStoreConnection<'a> {
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.gpos_quads( self.gpos_quads(encode_term_triple(graph_name, predicate, object)?)
&encode_term_triple(graph_name, predicate, object)?,
EncodedQuadPattern::new(None, Some(predicate), Some(object), Some(graph_name)),
)
} }
fn quads_for_object_graph( fn quads_for_object_graph(
@ -397,102 +358,75 @@ impl<'a> RocksDbStoreConnection<'a> {
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.gosp_quads( self.gosp_quads(encode_term_pair(graph_name, object)?)
&encode_term_pair(graph_name, object)?,
EncodedQuadPattern::new(None, None, Some(object), Some(graph_name)),
)
} }
fn spog_quads( fn spog_quads(
&self, &self,
start: &[u8], prefix: Vec<u8>,
filter: EncodedQuadPattern,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.inner_quads( self.inner_quads(self.spog_cf, prefix, |buffer| {
self.spog_cf, Cursor::new(buffer).read_spog_quad()
&start, })
|buffer| Cursor::new(buffer).read_spog_quad(),
filter,
)
} }
fn posg_quads( fn posg_quads(
&self, &self,
start: &[u8], prefix: Vec<u8>,
filter: EncodedQuadPattern,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.inner_quads( self.inner_quads(self.posg_cf, prefix, |buffer| {
self.posg_cf, Cursor::new(buffer).read_posg_quad()
&start, })
|buffer| Cursor::new(buffer).read_posg_quad(),
filter,
)
} }
fn ospg_quads( fn ospg_quads(
&self, &self,
start: &[u8], prefix: Vec<u8>,
filter: EncodedQuadPattern,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.inner_quads( self.inner_quads(self.ospg_cf, prefix, |buffer| {
self.ospg_cf, Cursor::new(buffer).read_ospg_quad()
&start, })
|buffer| Cursor::new(buffer).read_ospg_quad(),
filter,
)
} }
fn gspo_quads( fn gspo_quads(
&self, &self,
start: &[u8], prefix: Vec<u8>,
filter: EncodedQuadPattern,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.inner_quads( self.inner_quads(self.gspo_cf, prefix, |buffer| {
self.gspo_cf, Cursor::new(buffer).read_gspo_quad()
&start, })
|buffer| Cursor::new(buffer).read_gspo_quad(),
filter,
)
} }
fn gpos_quads( fn gpos_quads(
&self, &self,
start: &[u8], prefix: Vec<u8>,
filter: EncodedQuadPattern,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.inner_quads( self.inner_quads(self.gpos_cf, prefix, |buffer| {
self.gpos_cf, Cursor::new(buffer).read_gpos_quad()
&start, })
|buffer| Cursor::new(buffer).read_gpos_quad(),
filter,
)
} }
fn gosp_quads( fn gosp_quads(
&self, &self,
start: &[u8], prefix: Vec<u8>,
filter: EncodedQuadPattern,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
self.inner_quads( self.inner_quads(self.gosp_cf, prefix, |buffer| {
self.gosp_cf, Cursor::new(buffer).read_gosp_quad()
&start, })
|buffer| Cursor::new(buffer).read_gosp_quad(),
filter,
)
} }
fn inner_quads( fn inner_quads(
&self, &self,
cf: ColumnFamily, cf: ColumnFamily,
start: &[u8], prefix: Vec<u8>,
decode: impl Fn(&[u8]) -> Result<EncodedQuad> + 'a, decode: impl Fn(&[u8]) -> Result<EncodedQuad> + 'a,
filter: EncodedQuadPattern,
) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Result<impl Iterator<Item = Result<EncodedQuad>> + 'a> {
let mut iter = self.store.db.raw_iterator_cf(cf)?; let mut iter = self.store.db.raw_iterator_cf(cf)?;
iter.seek(&start); iter.seek(&prefix);
Ok(FilteringEncodedQuadsIterator { Ok(DecodingIndexIterator {
iter: DecodingIndexIterator { iter, decode }, iter,
filter, prefix,
decode,
}) })
} }
} }
@ -612,53 +546,6 @@ fn wrap_error<'a, E: 'a, I: Iterator<Item = Result<E>> + 'a>(
} }
} }
struct EncodedQuadPattern {
subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
}
impl EncodedQuadPattern {
fn new(
subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
) -> Self {
Self {
subject,
predicate,
object,
graph_name,
}
}
fn filter(&self, quad: &EncodedQuad) -> bool {
if let Some(ref subject) = self.subject {
if &quad.subject != subject {
return false;
}
}
if let Some(ref predicate) = self.predicate {
if &quad.predicate != predicate {
return false;
}
}
if let Some(ref object) = self.object {
if &quad.object != object {
return false;
}
}
if let Some(ref graph_name) = self.graph_name {
if &quad.graph_name != graph_name {
return false;
}
}
true
}
}
fn encode_term(t: EncodedTerm) -> Result<Vec<u8>> { fn encode_term(t: EncodedTerm) -> Result<Vec<u8>> {
let mut vec = Vec::with_capacity(WRITTEN_TERM_MAX_SIZE); let mut vec = Vec::with_capacity(WRITTEN_TERM_MAX_SIZE);
vec.write_term(t)?; vec.write_term(t)?;
@ -682,6 +569,7 @@ fn encode_term_triple(t1: EncodedTerm, t2: EncodedTerm, t3: EncodedTerm) -> Resu
struct DecodingIndexIterator<'a, F: Fn(&[u8]) -> Result<EncodedQuad>> { struct DecodingIndexIterator<'a, F: Fn(&[u8]) -> Result<EncodedQuad>> {
iter: DBRawIterator<'a>, iter: DBRawIterator<'a>,
prefix: Vec<u8>,
decode: F, decode: F,
} }
@ -690,7 +578,15 @@ impl<'a, F: Fn(&[u8]) -> Result<EncodedQuad>> Iterator for DecodingIndexIterator
fn next(&mut self) -> Option<Result<EncodedQuad>> { fn next(&mut self) -> Option<Result<EncodedQuad>> {
if self.iter.valid() { if self.iter.valid() {
let result = unsafe { self.iter.key_inner().map(|buffer| (self.decode)(buffer)) }; let result = unsafe {
self.iter.key_inner().and_then(|key| {
if key.starts_with(&self.prefix) {
Some((self.decode)(key))
} else {
None
}
})
};
self.iter.next(); self.iter.next();
result result
} else { } else {
@ -699,22 +595,6 @@ impl<'a, F: Fn(&[u8]) -> Result<EncodedQuad>> Iterator for DecodingIndexIterator
} }
} }
struct FilteringEncodedQuadsIterator<I: Iterator<Item = Result<EncodedQuad>>> {
iter: I,
filter: EncodedQuadPattern,
}
impl<I: Iterator<Item = Result<EncodedQuad>>> Iterator for FilteringEncodedQuadsIterator<I> {
type Item = Result<EncodedQuad>;
fn next(&mut self) -> Option<Result<EncodedQuad>> {
self.iter.next().filter(|quad| match quad {
Ok(quad) => self.filter.filter(quad),
Err(_) => true,
})
}
}
pub struct RocksString { pub struct RocksString {
vec: DBVector, vec: DBVector,
} }
@ -752,6 +632,11 @@ fn repository() -> Result<()> {
let main_o = Term::from(Literal::from(1)); let main_o = Term::from(Literal::from(1));
let main_quad = Quad::new(main_s.clone(), main_p.clone(), main_o.clone(), None); let main_quad = Quad::new(main_s.clone(), main_p.clone(), main_o.clone(), None);
let all_o = vec![
Quad::new(main_s.clone(), main_p.clone(), Literal::from(0), None),
Quad::new(main_s.clone(), main_p.clone(), main_o.clone(), None),
Quad::new(main_s.clone(), main_p.clone(), Literal::from(2), None),
];
let mut repo_path = temp_dir(); let mut repo_path = temp_dir();
repo_path.push(random::<u128>().to_string()); repo_path.push(random::<u128>().to_string());
@ -760,25 +645,28 @@ fn repository() -> Result<()> {
let repository = RocksDbRepository::open(&repo_path)?; let repository = RocksDbRepository::open(&repo_path)?;
let mut connection = repository.connection()?; let mut connection = repository.connection()?;
connection.insert(&main_quad)?; connection.insert(&main_quad)?;
for t in &all_o {
connection.insert(&t)?;
}
let target = vec![main_quad]; let target = vec![main_quad];
assert_eq!( assert_eq!(
connection connection
.quads_for_pattern(None, None, None, None) .quads_for_pattern(None, None, None, None)
.collect::<Result<Vec<_>>>()?, .collect::<Result<Vec<_>>>()?,
target all_o
); );
assert_eq!( assert_eq!(
connection connection
.quads_for_pattern(Some(&main_s), None, None, None) .quads_for_pattern(Some(&main_s), None, None, None)
.collect::<Result<Vec<_>>>()?, .collect::<Result<Vec<_>>>()?,
target all_o
); );
assert_eq!( assert_eq!(
connection connection
.quads_for_pattern(Some(&main_s), Some(&main_p), None, None) .quads_for_pattern(Some(&main_s), Some(&main_p), None, None)
.collect::<Result<Vec<_>>>()?, .collect::<Result<Vec<_>>>()?,
target all_o
); );
assert_eq!( assert_eq!(
connection connection
@ -796,7 +684,7 @@ fn repository() -> Result<()> {
connection connection
.quads_for_pattern(Some(&main_s), Some(&main_p), None, Some(None)) .quads_for_pattern(Some(&main_s), Some(&main_p), None, Some(None))
.collect::<Result<Vec<_>>>()?, .collect::<Result<Vec<_>>>()?,
target all_o
); );
assert_eq!( assert_eq!(
connection connection
@ -814,13 +702,13 @@ fn repository() -> Result<()> {
connection connection
.quads_for_pattern(Some(&main_s), None, None, Some(None)) .quads_for_pattern(Some(&main_s), None, None, Some(None))
.collect::<Result<Vec<_>>>()?, .collect::<Result<Vec<_>>>()?,
target all_o
); );
assert_eq!( assert_eq!(
connection connection
.quads_for_pattern(None, Some(&main_p), None, None) .quads_for_pattern(None, Some(&main_p), None, None)
.collect::<Result<Vec<_>>>()?, .collect::<Result<Vec<_>>>()?,
target all_o
); );
assert_eq!( assert_eq!(
connection connection
@ -838,7 +726,7 @@ fn repository() -> Result<()> {
connection connection
.quads_for_pattern(None, None, None, Some(None)) .quads_for_pattern(None, None, None, Some(None))
.collect::<Result<Vec<_>>>()?, .collect::<Result<Vec<_>>>()?,
target all_o
); );
assert_eq!( assert_eq!(
connection connection

Loading…
Cancel
Save