Drops InMemoryGraph in favor of the new memory storepull/10/head
parent
c48638d179
commit
38a8f97254
@ -1,187 +1,457 @@ |
|||||||
use model::vocab::rdf; |
use errors::*; |
||||||
use model::*; |
use std::collections::BTreeMap; |
||||||
use std::collections::HashSet; |
use std::collections::BTreeSet; |
||||||
use std::fmt; |
use std::sync::RwLock; |
||||||
use std::iter::FromIterator; |
use store::numeric_encoder::*; |
||||||
|
use store::store::*; |
||||||
#[derive(Debug, Clone, Default)] |
|
||||||
pub struct MemoryGraph { |
pub type MemoryDataset = StoreDataset<MemoryStore>; |
||||||
triples: HashSet<Triple>, |
pub type MemoryGraph = StoreDefaultGraph<MemoryStore>; |
||||||
|
|
||||||
|
#[derive(Default)] |
||||||
|
pub struct MemoryStore { |
||||||
|
id2str: RwLock<BTreeMap<u64, Vec<u8>>>, |
||||||
|
str2id: RwLock<BTreeMap<Vec<u8>, u64>>, |
||||||
|
graph_indexes: RwLock<BTreeMap<EncodedTerm, MemoryGraphIndexes>>, |
||||||
} |
} |
||||||
|
|
||||||
impl MemoryGraph { |
#[derive(Default)] |
||||||
pub fn iter(&self) -> impl Iterator<Item = &Triple> { |
struct MemoryGraphIndexes { |
||||||
self.triples.iter() |
spo: BTreeMap<EncodedTerm, BTreeMap<EncodedTerm, BTreeSet<EncodedTerm>>>, |
||||||
} |
pos: BTreeMap<EncodedTerm, BTreeMap<EncodedTerm, BTreeSet<EncodedTerm>>>, |
||||||
|
osp: BTreeMap<EncodedTerm, BTreeMap<EncodedTerm, BTreeSet<EncodedTerm>>>, |
||||||
|
} |
||||||
|
|
||||||
pub fn triples_for_subject<'a>( |
impl BytesStore for MemoryStore { |
||||||
&'a self, |
type BytesOutput = Vec<u8>; |
||||||
subject: &'a NamedOrBlankNode, |
|
||||||
) -> impl Iterator<Item = &'a Triple> { |
|
||||||
self.iter().filter(move |t| t.subject() == subject) |
|
||||||
} |
|
||||||
|
|
||||||
pub fn triples_for_predicate<'a>( |
fn insert_bytes(&self, value: &[u8]) -> Result<u64> { |
||||||
&'a self, |
let mut id2str = self.id2str.write()?; |
||||||
predicate: &'a NamedNode, |
let mut str2id = self.str2id.write()?; |
||||||
) -> impl Iterator<Item = &'a Triple> { |
let id = str2id.entry(value.to_vec()).or_insert_with(|| { |
||||||
self.iter().filter(move |t| t.predicate() == predicate) |
let id = id2str.len() as u64; |
||||||
|
id2str.insert(id, value.to_vec()); |
||||||
|
id |
||||||
|
}); |
||||||
|
Ok(*id) |
||||||
} |
} |
||||||
|
|
||||||
pub fn triples_for_object<'a>(&'a self, object: &'a Term) -> impl Iterator<Item = &'a Triple> { |
fn get_bytes(&self, id: u64) -> Result<Option<Vec<u8>>> { |
||||||
self.iter().filter(move |t| t.object() == object) |
Ok(self.id2str.read()?.get(&id).map(|s| s.to_owned())) |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
pub fn triples_for_subject_predicate<'a>( |
impl EncodedQuadsStore for MemoryStore { |
||||||
&'a self, |
type QuadsIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
subject: &'a NamedOrBlankNode, |
type QuadsForSubjectIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
predicate: &'a NamedNode, |
type QuadsForSubjectPredicateIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
) -> impl Iterator<Item = &'a Triple> { |
type QuadsForSubjectPredicateObjectIterator = |
||||||
self.iter() |
<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
.filter(move |t| t.subject() == subject && t.predicate() == predicate) |
type QuadsForSubjectObjectIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
} |
type QuadsForPredicateIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForPredicateObjectIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForObjectIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForGraphIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForSubjectGraphIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForSubjectPredicateGraphIterator = |
||||||
|
<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForSubjectObjectGraphIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForPredicateGraphIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForPredicateObjectGraphIterator = |
||||||
|
<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
type QuadsForObjectGraphIterator = <Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter; |
||||||
|
|
||||||
pub fn objects_for_subject_predicate<'a>( |
fn quads(&self) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
&'a self, |
let mut result = Vec::default(); |
||||||
subject: &'a NamedOrBlankNode, |
for (graph_name, graph) in self.graph_indexes.read()?.iter() { |
||||||
predicate: &'a NamedNode, |
for (s, pos) in graph.spo.iter() { |
||||||
) -> impl Iterator<Item = &'a Term> { |
for (p, os) in pos.iter() { |
||||||
self.triples_for_subject_predicate(subject, predicate) |
for o in os.iter() { |
||||||
.map(|t| t.object()) |
result.push(Ok(encoded_quad(s, p, o, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn object_for_subject_predicate<'a>( |
fn quads_for_subject( |
||||||
&'a self, |
&self, |
||||||
subject: &'a NamedOrBlankNode, |
subject: &EncodedTerm, |
||||||
predicate: &'a NamedNode, |
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
) -> Option<&'a Term> { |
let mut result = Vec::default(); |
||||||
self.objects_for_subject_predicate(subject, predicate) |
for (graph_name, graph) in self.graph_indexes.read()?.iter() { |
||||||
.nth(0) |
if let Some(pos) = graph.spo.get(subject) { |
||||||
|
for (p, os) in pos.iter() { |
||||||
|
for o in os.iter() { |
||||||
|
result.push(Ok(encoded_quad(subject, p, o, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn triples_for_predicate_object<'a>( |
fn quads_for_subject_predicate( |
||||||
&'a self, |
&self, |
||||||
predicate: &'a NamedNode, |
subject: &EncodedTerm, |
||||||
object: &'a Term, |
predicate: &EncodedTerm, |
||||||
) -> impl Iterator<Item = &'a Triple> { |
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
self.iter() |
let mut result = Vec::default(); |
||||||
.filter(move |t| t.predicate() == predicate && t.object() == object) |
for (graph_name, graph) in self.graph_indexes.read()?.iter() { |
||||||
|
if let Some(pos) = graph.spo.get(subject) { |
||||||
|
if let Some(os) = pos.get(predicate) { |
||||||
|
for o in os.iter() { |
||||||
|
result.push(Ok(encoded_quad(subject, predicate, o, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn subjects_for_predicate_object<'a>( |
fn quads_for_subject_predicate_object( |
||||||
&'a self, |
&self, |
||||||
predicate: &'a NamedNode, |
subject: &EncodedTerm, |
||||||
object: &'a Term, |
predicate: &EncodedTerm, |
||||||
) -> impl Iterator<Item = &'a NamedOrBlankNode> { |
object: &EncodedTerm, |
||||||
self.triples_for_predicate_object(predicate, object) |
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
.map(|t| t.subject()) |
let mut result = Vec::default(); |
||||||
|
for (graph_name, graph) in self.graph_indexes.read()?.iter() { |
||||||
|
if let Some(pos) = graph.spo.get(subject) { |
||||||
|
if let Some(os) = pos.get(predicate) { |
||||||
|
if os.contains(object) { |
||||||
|
result.push(Ok(encoded_quad(subject, predicate, object, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn subject_for_predicate_object<'a>( |
fn quads_for_subject_object( |
||||||
&'a self, |
&self, |
||||||
predicate: &'a NamedNode, |
subject: &EncodedTerm, |
||||||
object: &'a Term, |
object: &EncodedTerm, |
||||||
) -> Option<&'a NamedOrBlankNode> { |
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
self.subjects_for_predicate_object(predicate, object).nth(0) |
let mut result = Vec::default(); |
||||||
|
for (graph_name, graph) in self.graph_indexes.read()?.iter() { |
||||||
|
if let Some(sps) = graph.osp.get(object) { |
||||||
|
if let Some(ps) = sps.get(subject) { |
||||||
|
for p in ps.iter() { |
||||||
|
result.push(Ok(encoded_quad(subject, p, object, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn values_for_list<'a>(&'a self, root: NamedOrBlankNode) -> ListIterator<'a> { |
fn quads_for_predicate( |
||||||
ListIterator { |
&self, |
||||||
graph: self, |
predicate: &EncodedTerm, |
||||||
current_node: Some(root), |
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
for (graph_name, graph) in self.graph_indexes.read()?.iter() { |
||||||
|
if let Some(oss) = graph.pos.get(predicate) { |
||||||
|
for (o, ss) in oss.iter() { |
||||||
|
for s in ss.iter() { |
||||||
|
result.push(Ok(encoded_quad(s, predicate, o, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
} |
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn len(&self) -> usize { |
fn quads_for_predicate_object( |
||||||
self.triples.len() |
&self, |
||||||
|
predicate: &EncodedTerm, |
||||||
|
object: &EncodedTerm, |
||||||
|
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
for (graph_name, graph) in self.graph_indexes.read()?.iter() { |
||||||
|
if let Some(oss) = graph.pos.get(predicate) { |
||||||
|
if let Some(ss) = oss.get(object) { |
||||||
|
for s in ss.iter() { |
||||||
|
result.push(Ok(encoded_quad(s, predicate, object, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn is_empty(&self) -> bool { |
fn quads_for_object( |
||||||
self.triples.is_empty() |
&self, |
||||||
|
object: &EncodedTerm, |
||||||
|
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
for (graph_name, graph) in self.graph_indexes.read()?.iter() { |
||||||
|
if let Some(sps) = graph.osp.get(object) { |
||||||
|
for (s, ps) in sps.iter() { |
||||||
|
for p in ps.iter() { |
||||||
|
result.push(Ok(encoded_quad(s, p, object, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn contains(&self, value: &Triple) -> bool { |
fn quads_for_graph( |
||||||
self.triples.contains(value) |
&self, |
||||||
|
graph_name: &EncodedTerm, |
||||||
|
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
if let Some(graph) = self.graph_indexes.read()?.get(graph_name) { |
||||||
|
for (s, pos) in graph.spo.iter() { |
||||||
|
for (p, os) in pos.iter() { |
||||||
|
for o in os.iter() { |
||||||
|
result.push(Ok(encoded_quad(s, p, o, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
|
|
||||||
pub fn insert(&mut self, value: Triple) -> bool { |
fn quads_for_subject_graph( |
||||||
self.triples.insert(value) |
&self, |
||||||
|
subject: &EncodedTerm, |
||||||
|
graph_name: &EncodedTerm, |
||||||
|
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
if let Some(graph) = self.graph_indexes.read()?.get(graph_name) { |
||||||
|
if let Some(pos) = graph.spo.get(subject) { |
||||||
|
for (p, os) in pos.iter() { |
||||||
|
for o in os.iter() { |
||||||
|
result.push(Ok(encoded_quad(subject, p, o, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
impl fmt::Display for MemoryGraph { |
fn quads_for_subject_predicate_graph( |
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
&self, |
||||||
for triple in &self.triples { |
subject: &EncodedTerm, |
||||||
write!(fmt, "{}\n", triple)?; |
predicate: &EncodedTerm, |
||||||
|
graph_name: &EncodedTerm, |
||||||
|
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
if let Some(graph) = self.graph_indexes.read()?.get(graph_name) { |
||||||
|
if let Some(pos) = graph.spo.get(subject) { |
||||||
|
if let Some(os) = pos.get(predicate) { |
||||||
|
for o in os.iter() { |
||||||
|
result.push(Ok(encoded_quad(subject, predicate, o, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
} |
} |
||||||
Ok(()) |
Ok(result.into_iter()) |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
impl IntoIterator for MemoryGraph { |
fn quads_for_subject_object_graph( |
||||||
type Item = Triple; |
&self, |
||||||
type IntoIter = <HashSet<Triple> as IntoIterator>::IntoIter; |
subject: &EncodedTerm, |
||||||
|
object: &EncodedTerm, |
||||||
fn into_iter(self) -> <Self as IntoIterator>::IntoIter { |
graph_name: &EncodedTerm, |
||||||
self.triples.into_iter() |
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
if let Some(graph) = self.graph_indexes.read()?.get(graph_name) { |
||||||
|
if let Some(sps) = graph.osp.get(object) { |
||||||
|
if let Some(ps) = sps.get(subject) { |
||||||
|
for p in ps.iter() { |
||||||
|
result.push(Ok(encoded_quad(subject, p, object, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
impl<'a> IntoIterator for &'a MemoryGraph { |
fn quads_for_predicate_graph( |
||||||
type Item = &'a Triple; |
&self, |
||||||
type IntoIter = <&'a HashSet<Triple> as IntoIterator>::IntoIter; |
predicate: &EncodedTerm, |
||||||
|
graph_name: &EncodedTerm, |
||||||
|
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
if let Some(graph) = self.graph_indexes.read()?.get(graph_name) { |
||||||
|
if let Some(oss) = graph.pos.get(predicate) { |
||||||
|
for (o, ss) in oss.iter() { |
||||||
|
for s in ss.iter() { |
||||||
|
result.push(Ok(encoded_quad(s, predicate, o, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
|
} |
||||||
|
|
||||||
fn into_iter(self) -> <Self as IntoIterator>::IntoIter { |
fn quads_for_predicate_object_graph( |
||||||
self.triples.iter() |
&self, |
||||||
|
predicate: &EncodedTerm, |
||||||
|
object: &EncodedTerm, |
||||||
|
graph_name: &EncodedTerm, |
||||||
|
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
if let Some(graph) = self.graph_indexes.read()?.get(graph_name) { |
||||||
|
if let Some(oss) = graph.pos.get(predicate) { |
||||||
|
if let Some(ss) = oss.get(object) { |
||||||
|
for s in ss.iter() { |
||||||
|
result.push(Ok(encoded_quad(s, predicate, object, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
impl FromIterator<Triple> for MemoryGraph { |
fn quads_for_object_graph( |
||||||
fn from_iter<I: IntoIterator<Item = Triple>>(iter: I) -> Self { |
&self, |
||||||
let triples = HashSet::from_iter(iter); |
object: &EncodedTerm, |
||||||
Self { triples } |
graph_name: &EncodedTerm, |
||||||
|
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { |
||||||
|
let mut result = Vec::default(); |
||||||
|
if let Some(graph) = self.graph_indexes.read()?.get(graph_name) { |
||||||
|
if let Some(sps) = graph.osp.get(object) { |
||||||
|
for (s, ps) in sps.iter() { |
||||||
|
for p in ps.iter() { |
||||||
|
result.push(Ok(encoded_quad(s, p, object, graph_name))) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(result.into_iter()) |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
impl Extend<Triple> for MemoryGraph { |
fn contains(&self, quad: &EncodedQuad) -> Result<bool> { |
||||||
fn extend<I: IntoIterator<Item = Triple>>(&mut self, iter: I) { |
Ok(self |
||||||
self.triples.extend(iter) |
.graph_indexes |
||||||
|
.read()? |
||||||
|
.get(&quad.graph_name) |
||||||
|
.map(|graph| { |
||||||
|
graph |
||||||
|
.spo |
||||||
|
.get(&quad.subject) |
||||||
|
.map(|po| { |
||||||
|
po.get(&quad.predicate) |
||||||
|
.map(|o| o.contains(&quad.object)) |
||||||
|
.unwrap_or(false) |
||||||
|
}) |
||||||
|
.unwrap_or(false) |
||||||
|
}) |
||||||
|
.unwrap_or(false)) |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
impl<'a> Extend<&'a Triple> for MemoryGraph { |
fn insert(&self, quad: &EncodedQuad) -> Result<()> { |
||||||
fn extend<I: IntoIterator<Item = &'a Triple>>(&mut self, iter: I) { |
let mut graph_indexes = self.graph_indexes.write()?; |
||||||
self.triples.extend(iter.into_iter().cloned()) |
let graph = graph_indexes |
||||||
|
.entry(quad.graph_name.clone()) |
||||||
|
.or_insert_with(MemoryGraphIndexes::default); |
||||||
|
graph |
||||||
|
.spo |
||||||
|
.entry(quad.subject.clone()) |
||||||
|
.or_default() |
||||||
|
.entry(quad.predicate.clone()) |
||||||
|
.or_default() |
||||||
|
.insert(quad.object.clone()); |
||||||
|
graph |
||||||
|
.pos |
||||||
|
.entry(quad.predicate.clone()) |
||||||
|
.or_default() |
||||||
|
.entry(quad.object.clone()) |
||||||
|
.or_default() |
||||||
|
.insert(quad.subject.clone()); |
||||||
|
graph |
||||||
|
.osp |
||||||
|
.entry(quad.object.clone()) |
||||||
|
.or_default() |
||||||
|
.entry(quad.subject.clone()) |
||||||
|
.or_default() |
||||||
|
.insert(quad.predicate.clone()); |
||||||
|
Ok(()) |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
pub struct ListIterator<'a> { |
fn remove(&self, quad: &EncodedQuad) -> Result<()> { |
||||||
graph: &'a MemoryGraph, |
let mut graph_indexes = self.graph_indexes.write()?; |
||||||
current_node: Option<NamedOrBlankNode>, |
let mut empty_graph = false; |
||||||
} |
if let Some(graph) = graph_indexes.get_mut(&quad.graph_name) { |
||||||
|
{ |
||||||
|
let mut empty_pos = false; |
||||||
|
if let Some(mut pos) = graph.spo.get_mut(&quad.subject) { |
||||||
|
let mut empty_os = false; |
||||||
|
if let Some(mut os) = pos.get_mut(&quad.predicate) { |
||||||
|
os.remove(&quad.object); |
||||||
|
empty_os = os.is_empty(); |
||||||
|
} |
||||||
|
if empty_os { |
||||||
|
pos.remove(&quad.predicate); |
||||||
|
} |
||||||
|
empty_pos = pos.is_empty(); |
||||||
|
} |
||||||
|
if empty_pos { |
||||||
|
graph.spo.remove(&quad.subject); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
{ |
||||||
|
let mut empty_oss = false; |
||||||
|
if let Some(mut oss) = graph.pos.get_mut(&quad.predicate) { |
||||||
|
let mut empty_ss = false; |
||||||
|
if let Some(mut ss) = oss.get_mut(&quad.object) { |
||||||
|
ss.remove(&quad.subject); |
||||||
|
empty_ss = ss.is_empty(); |
||||||
|
} |
||||||
|
if empty_ss { |
||||||
|
oss.remove(&quad.object); |
||||||
|
} |
||||||
|
empty_oss = oss.is_empty(); |
||||||
|
} |
||||||
|
if empty_oss { |
||||||
|
graph.pos.remove(&quad.predicate); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
{ |
||||||
|
let mut empty_sps = false; |
||||||
|
if let Some(mut sps) = graph.osp.get_mut(&quad.object) { |
||||||
|
let mut empty_ps = false; |
||||||
|
if let Some(mut ps) = sps.get_mut(&quad.subject) { |
||||||
|
ps.remove(&quad.predicate); |
||||||
|
empty_ps = ps.is_empty(); |
||||||
|
} |
||||||
|
if empty_ps { |
||||||
|
sps.remove(&quad.subject); |
||||||
|
} |
||||||
|
empty_sps = sps.is_empty(); |
||||||
|
} |
||||||
|
if empty_sps { |
||||||
|
graph.osp.remove(&quad.object); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
impl<'a> Iterator for ListIterator<'a> { |
empty_graph = graph.spo.is_empty(); |
||||||
type Item = Term; |
} |
||||||
|
if empty_graph { |
||||||
fn next(&mut self) -> Option<Term> { |
graph_indexes.remove(&quad.graph_name); |
||||||
match self.current_node.clone() { |
|
||||||
Some(current) => { |
|
||||||
let result = self |
|
||||||
.graph |
|
||||||
.object_for_subject_predicate(¤t, &rdf::FIRST)? |
|
||||||
.clone(); |
|
||||||
self.current_node = match self |
|
||||||
.graph |
|
||||||
.object_for_subject_predicate(¤t, &rdf::REST) |
|
||||||
{ |
|
||||||
Some(Term::NamedNode(n)) if *n == *rdf::NIL => None, |
|
||||||
Some(Term::NamedNode(n)) => Some(n.clone().into()), |
|
||||||
Some(Term::BlankNode(n)) => Some(n.clone().into()), |
|
||||||
_ => None, |
|
||||||
}; |
|
||||||
Some(result) |
|
||||||
} |
|
||||||
None => None, |
|
||||||
} |
} |
||||||
|
Ok(()) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
|
fn encoded_quad( |
||||||
|
subject: &EncodedTerm, |
||||||
|
predicate: &EncodedTerm, |
||||||
|
object: &EncodedTerm, |
||||||
|
graph_name: &EncodedTerm, |
||||||
|
) -> EncodedQuad { |
||||||
|
EncodedQuad::new( |
||||||
|
subject.clone(), |
||||||
|
predicate.clone(), |
||||||
|
object.clone(), |
||||||
|
graph_name.clone(), |
||||||
|
) |
||||||
|
} |
||||||
|
@ -1,524 +0,0 @@ |
|||||||
use errors::*; |
|
||||||
use rocksdb::ColumnFamily; |
|
||||||
use rocksdb::DBRawIterator; |
|
||||||
use rocksdb::DBVector; |
|
||||||
use rocksdb::Options; |
|
||||||
use rocksdb::WriteBatch; |
|
||||||
use rocksdb::DB; |
|
||||||
use std::io::Cursor; |
|
||||||
use std::mem::size_of; |
|
||||||
use std::path::Path; |
|
||||||
use std::str; |
|
||||||
use std::sync::Mutex; |
|
||||||
use store::numeric_encoder::*; |
|
||||||
use store::store::EncodedQuadsStore; |
|
||||||
use utils::from_bytes; |
|
||||||
use utils::from_bytes_slice; |
|
||||||
use utils::to_bytes; |
|
||||||
|
|
||||||
const ID2STR_CF: &'static str = "id2str"; |
|
||||||
const STR2ID_CF: &'static str = "id2str"; |
|
||||||
const SPOG_CF: &'static str = "spog"; |
|
||||||
const POSG_CF: &'static str = "posg"; |
|
||||||
const OSPG_CF: &'static str = "ospg"; |
|
||||||
|
|
||||||
const EMPTY_BUF: [u8; 0] = [0 as u8; 0]; |
|
||||||
|
|
||||||
//TODO: indexes for the default graph and indexes for the named graphs (no more Optional and space saving)
|
|
||||||
|
|
||||||
const COLUMN_FAMILIES: [&'static str; 5] = [ID2STR_CF, STR2ID_CF, SPOG_CF, POSG_CF, OSPG_CF]; |
|
||||||
|
|
||||||
pub struct RocksDbStore { |
|
||||||
db: DB, |
|
||||||
str_id_counter: Mutex<RocksDBCounter>, |
|
||||||
id2str_cf: ColumnFamily, |
|
||||||
str2id_cf: ColumnFamily, |
|
||||||
spog_cf: ColumnFamily, |
|
||||||
posg_cf: ColumnFamily, |
|
||||||
ospg_cf: ColumnFamily, |
|
||||||
} |
|
||||||
|
|
||||||
impl RocksDbStore { |
|
||||||
pub fn open(path: impl AsRef<Path>) -> Result<Self> { |
|
||||||
let mut options = Options::default(); |
|
||||||
options.create_if_missing(true); |
|
||||||
options.create_missing_column_families(true); |
|
||||||
|
|
||||||
let db = DB::open_cf(&options, path, &COLUMN_FAMILIES)?; |
|
||||||
let id2str_cf = get_cf(&db, STR2ID_CF)?; |
|
||||||
let str2id_cf = get_cf(&db, ID2STR_CF)?; |
|
||||||
let spog_cf = get_cf(&db, SPOG_CF)?; |
|
||||||
let posg_cf = get_cf(&db, POSG_CF)?; |
|
||||||
let ospg_cf = get_cf(&db, OSPG_CF)?; |
|
||||||
|
|
||||||
Ok(Self { |
|
||||||
db, |
|
||||||
str_id_counter: Mutex::new(RocksDBCounter::new("bsc")), |
|
||||||
id2str_cf, |
|
||||||
str2id_cf, |
|
||||||
spog_cf, |
|
||||||
posg_cf, |
|
||||||
ospg_cf, |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl BytesStore for RocksDbStore { |
|
||||||
type BytesOutput = DBVector; |
|
||||||
|
|
||||||
fn insert_bytes(&self, value: &[u8]) -> Result<u64> { |
|
||||||
Ok(match self.db.get_cf(self.str2id_cf, value)? { |
|
||||||
Some(id) => from_bytes_slice(&id), |
|
||||||
None => { |
|
||||||
let id = self |
|
||||||
.str_id_counter |
|
||||||
.lock() |
|
||||||
.unwrap() |
|
||||||
.get_and_increment(&self.db)? as u64; |
|
||||||
let id_bytes = to_bytes(id); |
|
||||||
let mut batch = WriteBatch::default(); |
|
||||||
batch.put_cf(self.id2str_cf, &id_bytes, value)?; |
|
||||||
batch.put_cf(self.str2id_cf, value, &id_bytes)?; |
|
||||||
self.db.write(batch)?; |
|
||||||
id |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn get_bytes(&self, id: u64) -> Result<Option<DBVector>> { |
|
||||||
Ok(self.db.get_cf(self.id2str_cf, &to_bytes(id))?) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl EncodedQuadsStore for RocksDbStore { |
|
||||||
type QuadsIterator = SPOGIndexIterator; |
|
||||||
type QuadsForSubjectIterator = FilteringEncodedQuadsIterator<SPOGIndexIterator>; |
|
||||||
type QuadsForSubjectPredicateIterator = FilteringEncodedQuadsIterator<SPOGIndexIterator>; |
|
||||||
type QuadsForSubjectPredicateObjectIterator = FilteringEncodedQuadsIterator<SPOGIndexIterator>; |
|
||||||
type QuadsForSubjectObjectIterator = FilteringEncodedQuadsIterator<OSPGIndexIterator>; |
|
||||||
type QuadsForPredicateIterator = FilteringEncodedQuadsIterator<POSGIndexIterator>; |
|
||||||
type QuadsForPredicateObjectIterator = FilteringEncodedQuadsIterator<POSGIndexIterator>; |
|
||||||
type QuadsForObjectIterator = FilteringEncodedQuadsIterator<OSPGIndexIterator>; |
|
||||||
type QuadsForGraphIterator = InGraphQuadsIterator<SPOGIndexIterator>; |
|
||||||
type QuadsForSubjectGraphIterator = |
|
||||||
InGraphQuadsIterator<FilteringEncodedQuadsIterator<SPOGIndexIterator>>; |
|
||||||
type QuadsForSubjectPredicateGraphIterator = |
|
||||||
InGraphQuadsIterator<FilteringEncodedQuadsIterator<SPOGIndexIterator>>; |
|
||||||
type QuadsForSubjectObjectGraphIterator = |
|
||||||
InGraphQuadsIterator<FilteringEncodedQuadsIterator<OSPGIndexIterator>>; |
|
||||||
type QuadsForPredicateGraphIterator = |
|
||||||
InGraphQuadsIterator<FilteringEncodedQuadsIterator<POSGIndexIterator>>; |
|
||||||
type QuadsForPredicateObjectGraphIterator = |
|
||||||
InGraphQuadsIterator<FilteringEncodedQuadsIterator<POSGIndexIterator>>; |
|
||||||
type QuadsForObjectGraphIterator = |
|
||||||
InGraphQuadsIterator<FilteringEncodedQuadsIterator<OSPGIndexIterator>>; |
|
||||||
|
|
||||||
fn quads(&self) -> Result<SPOGIndexIterator> { |
|
||||||
let mut iter = self.db.raw_iterator_cf(self.spog_cf)?; |
|
||||||
iter.seek_to_first(); |
|
||||||
Ok(SPOGIndexIterator { iter }) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject( |
|
||||||
&self, |
|
||||||
subject: &EncodedTerm, |
|
||||||
) -> Result<FilteringEncodedQuadsIterator<SPOGIndexIterator>> { |
|
||||||
let mut iter = self.db.raw_iterator_cf(self.spog_cf)?; |
|
||||||
iter.seek(&encode_term(subject)?); |
|
||||||
Ok(FilteringEncodedQuadsIterator { |
|
||||||
iter: SPOGIndexIterator { iter }, |
|
||||||
filter: EncodedQuadPattern::new(Some(subject.clone()), None, None, None), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_predicate( |
|
||||||
&self, |
|
||||||
subject: &EncodedTerm, |
|
||||||
predicate: &EncodedTerm, |
|
||||||
) -> Result<FilteringEncodedQuadsIterator<SPOGIndexIterator>> { |
|
||||||
let mut iter = self.db.raw_iterator_cf(self.spog_cf)?; |
|
||||||
iter.seek(&encode_term_pair(subject, predicate)?); |
|
||||||
Ok(FilteringEncodedQuadsIterator { |
|
||||||
iter: SPOGIndexIterator { iter }, |
|
||||||
filter: EncodedQuadPattern::new( |
|
||||||
Some(subject.clone()), |
|
||||||
Some(predicate.clone()), |
|
||||||
None, |
|
||||||
None, |
|
||||||
), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_predicate_object( |
|
||||||
&self, |
|
||||||
subject: &EncodedTerm, |
|
||||||
predicate: &EncodedTerm, |
|
||||||
object: &EncodedTerm, |
|
||||||
) -> Result<FilteringEncodedQuadsIterator<SPOGIndexIterator>> { |
|
||||||
let mut iter = self.db.raw_iterator_cf(self.spog_cf)?; |
|
||||||
iter.seek(&encode_term_triple(subject, predicate, object)?); |
|
||||||
Ok(FilteringEncodedQuadsIterator { |
|
||||||
iter: SPOGIndexIterator { iter }, |
|
||||||
filter: EncodedQuadPattern::new( |
|
||||||
Some(subject.clone()), |
|
||||||
Some(predicate.clone()), |
|
||||||
Some(object.clone()), |
|
||||||
None, |
|
||||||
), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_object( |
|
||||||
&self, |
|
||||||
subject: &EncodedTerm, |
|
||||||
object: &EncodedTerm, |
|
||||||
) -> Result<FilteringEncodedQuadsIterator<OSPGIndexIterator>> { |
|
||||||
let mut iter = self.db.raw_iterator_cf(self.spog_cf)?; |
|
||||||
iter.seek(&encode_term_pair(object, subject)?); |
|
||||||
Ok(FilteringEncodedQuadsIterator { |
|
||||||
iter: OSPGIndexIterator { iter }, |
|
||||||
filter: EncodedQuadPattern::new( |
|
||||||
Some(subject.clone()), |
|
||||||
None, |
|
||||||
Some(object.clone()), |
|
||||||
None, |
|
||||||
), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_predicate( |
|
||||||
&self, |
|
||||||
predicate: &EncodedTerm, |
|
||||||
) -> Result<FilteringEncodedQuadsIterator<POSGIndexIterator>> { |
|
||||||
let mut iter = self.db.raw_iterator_cf(self.posg_cf)?; |
|
||||||
iter.seek(&encode_term(predicate)?); |
|
||||||
Ok(FilteringEncodedQuadsIterator { |
|
||||||
iter: POSGIndexIterator { iter }, |
|
||||||
filter: EncodedQuadPattern::new(None, Some(predicate.clone()), None, None), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_predicate_object( |
|
||||||
&self, |
|
||||||
predicate: &EncodedTerm, |
|
||||||
object: &EncodedTerm, |
|
||||||
) -> Result<FilteringEncodedQuadsIterator<POSGIndexIterator>> { |
|
||||||
let mut iter = self.db.raw_iterator_cf(self.spog_cf)?; |
|
||||||
iter.seek(&encode_term_pair(predicate, object)?); |
|
||||||
Ok(FilteringEncodedQuadsIterator { |
|
||||||
iter: POSGIndexIterator { iter }, |
|
||||||
filter: EncodedQuadPattern::new( |
|
||||||
None, |
|
||||||
Some(predicate.clone()), |
|
||||||
Some(object.clone()), |
|
||||||
None, |
|
||||||
), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_object( |
|
||||||
&self, |
|
||||||
object: &EncodedTerm, |
|
||||||
) -> Result<FilteringEncodedQuadsIterator<OSPGIndexIterator>> { |
|
||||||
let mut iter = self.db.raw_iterator_cf(self.ospg_cf)?; |
|
||||||
iter.seek(&encode_term(&object)?); |
|
||||||
Ok(FilteringEncodedQuadsIterator { |
|
||||||
iter: OSPGIndexIterator { iter }, |
|
||||||
filter: EncodedQuadPattern::new(None, None, Some(object.clone()), None), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_graph( |
|
||||||
&self, |
|
||||||
graph_name: &EncodedTerm, |
|
||||||
) -> Result<InGraphQuadsIterator<SPOGIndexIterator>> { |
|
||||||
Ok(InGraphQuadsIterator { |
|
||||||
iter: self.quads()?, |
|
||||||
graph_name: graph_name.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_graph( |
|
||||||
&self, |
|
||||||
subject: &EncodedTerm, |
|
||||||
graph_name: &EncodedTerm, |
|
||||||
) -> Result<InGraphQuadsIterator<FilteringEncodedQuadsIterator<SPOGIndexIterator>>> { |
|
||||||
Ok(InGraphQuadsIterator { |
|
||||||
iter: self.quads_for_subject(subject)?, |
|
||||||
graph_name: graph_name.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_predicate_graph( |
|
||||||
&self, |
|
||||||
subject: &EncodedTerm, |
|
||||||
predicate: &EncodedTerm, |
|
||||||
graph_name: &EncodedTerm, |
|
||||||
) -> Result<InGraphQuadsIterator<FilteringEncodedQuadsIterator<SPOGIndexIterator>>> { |
|
||||||
Ok(InGraphQuadsIterator { |
|
||||||
iter: self.quads_for_subject_predicate(subject, predicate)?, |
|
||||||
graph_name: graph_name.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_subject_object_graph( |
|
||||||
&self, |
|
||||||
subject: &EncodedTerm, |
|
||||||
object: &EncodedTerm, |
|
||||||
graph_name: &EncodedTerm, |
|
||||||
) -> Result<InGraphQuadsIterator<FilteringEncodedQuadsIterator<OSPGIndexIterator>>> { |
|
||||||
Ok(InGraphQuadsIterator { |
|
||||||
iter: self.quads_for_subject_object(subject, object)?, |
|
||||||
graph_name: graph_name.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_predicate_graph( |
|
||||||
&self, |
|
||||||
predicate: &EncodedTerm, |
|
||||||
graph_name: &EncodedTerm, |
|
||||||
) -> Result<InGraphQuadsIterator<FilteringEncodedQuadsIterator<POSGIndexIterator>>> { |
|
||||||
Ok(InGraphQuadsIterator { |
|
||||||
iter: self.quads_for_predicate(predicate)?, |
|
||||||
graph_name: graph_name.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_predicate_object_graph( |
|
||||||
&self, |
|
||||||
predicate: &EncodedTerm, |
|
||||||
object: &EncodedTerm, |
|
||||||
graph_name: &EncodedTerm, |
|
||||||
) -> Result<InGraphQuadsIterator<FilteringEncodedQuadsIterator<POSGIndexIterator>>> { |
|
||||||
Ok(InGraphQuadsIterator { |
|
||||||
iter: self.quads_for_predicate_object(predicate, object)?, |
|
||||||
graph_name: graph_name.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn quads_for_object_graph( |
|
||||||
&self, |
|
||||||
object: &EncodedTerm, |
|
||||||
graph_name: &EncodedTerm, |
|
||||||
) -> Result<InGraphQuadsIterator<FilteringEncodedQuadsIterator<OSPGIndexIterator>>> { |
|
||||||
Ok(InGraphQuadsIterator { |
|
||||||
iter: self.quads_for_object(object)?, |
|
||||||
graph_name: graph_name.clone(), |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn contains(&self, quad: &EncodedQuad) -> Result<bool> { |
|
||||||
Ok(self |
|
||||||
.db |
|
||||||
.get_cf(self.spog_cf, &encode_spog_quad(quad)?)? |
|
||||||
.is_some()) |
|
||||||
} |
|
||||||
|
|
||||||
fn insert(&self, quad: &EncodedQuad) -> Result<()> { |
|
||||||
let mut batch = WriteBatch::default(); |
|
||||||
batch.put_cf(self.spog_cf, &encode_spog_quad(quad)?, &EMPTY_BUF)?; |
|
||||||
batch.put_cf(self.posg_cf, &encode_posg_quad(quad)?, &EMPTY_BUF)?; |
|
||||||
batch.put_cf(self.ospg_cf, &encode_ospg_quad(quad)?, &EMPTY_BUF)?; |
|
||||||
Ok(self.db.write(batch)?) //TODO: check what's going on if the key already exists
|
|
||||||
} |
|
||||||
|
|
||||||
fn remove(&self, quad: &EncodedQuad) -> Result<()> { |
|
||||||
let mut batch = WriteBatch::default(); |
|
||||||
batch.delete_cf(self.spog_cf, &encode_spog_quad(quad)?)?; |
|
||||||
batch.delete_cf(self.posg_cf, &encode_posg_quad(quad)?)?; |
|
||||||
batch.delete_cf(self.ospg_cf, &encode_ospg_quad(quad)?)?; |
|
||||||
Ok(self.db.write(batch)?) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub fn get_cf(db: &DB, name: &str) -> Result<ColumnFamily> { |
|
||||||
db.cf_handle(name) |
|
||||||
.ok_or_else(|| "column family not found".into()) |
|
||||||
} |
|
||||||
|
|
||||||
struct RocksDBCounter { |
|
||||||
name: &'static str, |
|
||||||
} |
|
||||||
|
|
||||||
impl RocksDBCounter { |
|
||||||
fn new(name: &'static str) -> Self { |
|
||||||
Self { name } |
|
||||||
} |
|
||||||
|
|
||||||
fn get_and_increment(&self, db: &DB) -> Result<u64> { |
|
||||||
let value = db |
|
||||||
.get(self.name.as_bytes())? |
|
||||||
.map(|b| { |
|
||||||
let mut buf = [0 as u8; size_of::<usize>()]; |
|
||||||
buf.copy_from_slice(&b); |
|
||||||
from_bytes(buf) |
|
||||||
}) |
|
||||||
.unwrap_or(0); |
|
||||||
db.put(self.name.as_bytes(), &to_bytes(value + 1))?; |
|
||||||
Ok(value) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
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>> { |
|
||||||
let mut vec = Vec::default(); |
|
||||||
vec.write_term(&t)?; |
|
||||||
Ok(vec) |
|
||||||
} |
|
||||||
|
|
||||||
fn encode_term_pair(t1: &EncodedTerm, t2: &EncodedTerm) -> Result<Vec<u8>> { |
|
||||||
let mut vec = Vec::default(); |
|
||||||
vec.write_term(&t1)?; |
|
||||||
vec.write_term(&t2)?; |
|
||||||
Ok(vec) |
|
||||||
} |
|
||||||
|
|
||||||
fn encode_term_triple(t1: &EncodedTerm, t2: &EncodedTerm, t3: &EncodedTerm) -> Result<Vec<u8>> { |
|
||||||
let mut vec = Vec::default(); |
|
||||||
vec.write_term(&t1)?; |
|
||||||
vec.write_term(&t2)?; |
|
||||||
vec.write_term(&t3)?; |
|
||||||
Ok(vec) |
|
||||||
} |
|
||||||
|
|
||||||
fn encode_spog_quad(quad: &EncodedQuad) -> Result<Vec<u8>> { |
|
||||||
let mut vec = Vec::default(); |
|
||||||
vec.write_spog_quad(quad)?; |
|
||||||
Ok(vec) |
|
||||||
} |
|
||||||
|
|
||||||
fn encode_posg_quad(quad: &EncodedQuad) -> Result<Vec<u8>> { |
|
||||||
let mut vec = Vec::default(); |
|
||||||
vec.write_posg_quad(quad)?; |
|
||||||
Ok(vec) |
|
||||||
} |
|
||||||
|
|
||||||
fn encode_ospg_quad(quad: &EncodedQuad) -> Result<Vec<u8>> { |
|
||||||
let mut vec = Vec::default(); |
|
||||||
vec.write_ospg_quad(quad)?; |
|
||||||
Ok(vec) |
|
||||||
} |
|
||||||
|
|
||||||
pub struct SPOGIndexIterator { |
|
||||||
iter: DBRawIterator, |
|
||||||
} |
|
||||||
|
|
||||||
impl Iterator for SPOGIndexIterator { |
|
||||||
type Item = Result<EncodedQuad>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<EncodedQuad>> { |
|
||||||
self.iter.next(); |
|
||||||
self.iter |
|
||||||
.key() |
|
||||||
.map(|buffer| Cursor::new(buffer).read_spog_quad()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct POSGIndexIterator { |
|
||||||
iter: DBRawIterator, |
|
||||||
} |
|
||||||
|
|
||||||
impl Iterator for POSGIndexIterator { |
|
||||||
type Item = Result<EncodedQuad>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<EncodedQuad>> { |
|
||||||
self.iter.next(); |
|
||||||
self.iter |
|
||||||
.key() |
|
||||||
.map(|buffer| Cursor::new(buffer).read_posg_quad()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub struct OSPGIndexIterator { |
|
||||||
iter: DBRawIterator, |
|
||||||
} |
|
||||||
|
|
||||||
impl Iterator for OSPGIndexIterator { |
|
||||||
type Item = Result<EncodedQuad>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<EncodedQuad>> { |
|
||||||
self.iter.next(); |
|
||||||
self.iter |
|
||||||
.key() |
|
||||||
.map(|buffer| Cursor::new(buffer).read_ospg_quad()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub 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 InGraphQuadsIterator<I: Iterator<Item = Result<EncodedQuad>>> { |
|
||||||
iter: I, |
|
||||||
graph_name: EncodedTerm, |
|
||||||
} |
|
||||||
|
|
||||||
impl<I: Iterator<Item = Result<EncodedQuad>>> Iterator for InGraphQuadsIterator<I> { |
|
||||||
type Item = Result<EncodedQuad>; |
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Result<EncodedQuad>> { |
|
||||||
let graph_name = &self.graph_name; |
|
||||||
self.iter.find(|quad| match quad { |
|
||||||
Ok(quad) => graph_name == &quad.graph_name, |
|
||||||
Err(_) => true, |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue