From b01054a747d053655532ff6376f85f3460bc1eaa Mon Sep 17 00:00:00 2001 From: Tpt Date: Wed, 12 Sep 2018 11:38:19 +0200 Subject: [PATCH] Adds a special EncodedTerm for the default graph --- src/store/numeric_encoder.rs | 94 +++++++++++++++--------------------- src/store/rocksdb/storage.rs | 20 ++++---- src/store/store.rs | 87 ++++++++++++++++++--------------- 3 files changed, 98 insertions(+), 103 deletions(-) diff --git a/src/store/numeric_encoder.rs b/src/store/numeric_encoder.rs index c964b105..6eac616c 100644 --- a/src/store/numeric_encoder.rs +++ b/src/store/numeric_encoder.rs @@ -16,14 +16,17 @@ pub trait BytesStore { fn get_bytes(&self, id: u64) -> Result>; } -const TYPE_NOTHING_ID: u8 = 0; +const TYPE_DEFAULT_GRAPH_ID: u8 = 0; const TYPE_NAMED_NODE_ID: u8 = 1; const TYPE_BLANK_NODE_ID: u8 = 2; const TYPE_LANG_STRING_LITERAL_ID: u8 = 3; const TYPE_TYPED_LITERAL_ID: u8 = 4; +pub static ENCODED_DEFAULT_GRAPH: EncodedTerm = EncodedTerm::DefaultGraph {}; + #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] pub enum EncodedTerm { + DefaultGraph {}, NamedNode { iri_id: u64 }, BlankNode(Uuid), LangStringLiteral { value_id: u64, language_id: u64 }, @@ -33,6 +36,7 @@ pub enum EncodedTerm { impl EncodedTerm { fn type_id(&self) -> u8 { match self { + EncodedTerm::DefaultGraph { .. } => TYPE_DEFAULT_GRAPH_ID, EncodedTerm::NamedNode { .. } => TYPE_NAMED_NODE_ID, EncodedTerm::BlankNode(_) => TYPE_BLANK_NODE_ID, EncodedTerm::LangStringLiteral { .. } => TYPE_LANG_STRING_LITERAL_ID, @@ -46,12 +50,11 @@ pub struct EncodedQuad { pub subject: EncodedTerm, pub predicate: EncodedTerm, pub object: EncodedTerm, - pub graph_name: Option, + pub graph_name: EncodedTerm, } pub trait TermReader { fn read_term(&mut self) -> Result; - fn read_optional_term(&mut self) -> Result>; fn read_spog_quad(&mut self) -> Result; fn read_posg_quad(&mut self) -> Result; fn read_ospg_quad(&mut self) -> Result; @@ -59,16 +62,25 @@ pub trait TermReader { impl TermReader for R { fn read_term(&mut self) -> Result { - let type_id = self.read_u8()?; - read_term_after_type(self, type_id) - } - - fn read_optional_term(&mut self) -> Result> { - let type_id = self.read_u8()?; - if type_id == 0 { - Ok(None) - } else { - Ok(Some(read_term_after_type(self, type_id)?)) + match self.read_u8()? { + TYPE_DEFAULT_GRAPH_ID => Ok(EncodedTerm::DefaultGraph {}), + TYPE_NAMED_NODE_ID => Ok(EncodedTerm::NamedNode { + iri_id: self.read_u64::()?, + }), + TYPE_BLANK_NODE_ID => { + let mut uuid_buffer = [0 as u8; 16]; + self.read_exact(&mut uuid_buffer)?; + Ok(EncodedTerm::BlankNode(Uuid::from_bytes(&uuid_buffer)?)) + } + TYPE_LANG_STRING_LITERAL_ID => Ok(EncodedTerm::LangStringLiteral { + language_id: self.read_u64::()?, + value_id: self.read_u64::()?, + }), + TYPE_TYPED_LITERAL_ID => Ok(EncodedTerm::TypedLiteral { + datatype_id: self.read_u64::()?, + value_id: self.read_u64::()?, + }), + _ => Err("the term buffer has an invalid type id".into()), } } @@ -76,7 +88,7 @@ impl TermReader for R { let subject = self.read_term()?; let predicate = self.read_term()?; let object = self.read_term()?; - let graph_name = self.read_optional_term()?; + let graph_name = self.read_term()?; Ok(EncodedQuad { subject, predicate, @@ -89,7 +101,7 @@ impl TermReader for R { let predicate = self.read_term()?; let object = self.read_term()?; let subject = self.read_term()?; - let graph_name = self.read_optional_term()?; + let graph_name = self.read_term()?; Ok(EncodedQuad { subject, predicate, @@ -102,7 +114,7 @@ impl TermReader for R { let object = self.read_term()?; let subject = self.read_term()?; let predicate = self.read_term()?; - let graph_name = self.read_optional_term()?; + let graph_name = self.read_term()?; Ok(EncodedQuad { subject, predicate, @@ -112,31 +124,8 @@ impl TermReader for R { } } -fn read_term_after_type(reader: &mut impl Read, type_id: u8) -> Result { - match type_id { - TYPE_NAMED_NODE_ID => Ok(EncodedTerm::NamedNode { - iri_id: reader.read_u64::()?, - }), - TYPE_BLANK_NODE_ID => { - let mut uuid_buffer = [0 as u8; 16]; - reader.read_exact(&mut uuid_buffer)?; - Ok(EncodedTerm::BlankNode(Uuid::from_bytes(&uuid_buffer)?)) - } - TYPE_LANG_STRING_LITERAL_ID => Ok(EncodedTerm::LangStringLiteral { - language_id: reader.read_u64::()?, - value_id: reader.read_u64::()?, - }), - TYPE_TYPED_LITERAL_ID => Ok(EncodedTerm::TypedLiteral { - datatype_id: reader.read_u64::()?, - value_id: reader.read_u64::()?, - }), - _ => Err("the term buffer has an invalid type id".into()), - } -} - pub trait TermWriter { fn write_term(&mut self, term: &EncodedTerm) -> Result<()>; - fn write_optional_term(&mut self, term: &Option) -> Result<()>; fn write_spog_quad(&mut self, quad: &EncodedQuad) -> Result<()>; fn write_posg_quad(&mut self, quad: &EncodedQuad) -> Result<()>; fn write_ospg_quad(&mut self, quad: &EncodedQuad) -> Result<()>; @@ -146,6 +135,7 @@ impl TermWriter for R { fn write_term(&mut self, term: &EncodedTerm) -> Result<()> { self.write_u8(term.type_id())?; match term { + EncodedTerm::DefaultGraph {} => {} EncodedTerm::NamedNode { iri_id } => self.write_u64::(*iri_id)?, EncodedTerm::BlankNode(id) => self.write_all(id.as_bytes())?, EncodedTerm::LangStringLiteral { @@ -166,18 +156,11 @@ impl TermWriter for R { Ok(()) } - fn write_optional_term(&mut self, term: &Option) -> Result<()> { - match term { - Some(term) => self.write_term(term), - None => Ok(self.write_u8(TYPE_NOTHING_ID)?), - } - } - fn write_spog_quad(&mut self, quad: &EncodedQuad) -> Result<()> { self.write_term(&quad.subject)?; self.write_term(&quad.predicate)?; self.write_term(&quad.object)?; - self.write_optional_term(&quad.graph_name)?; + self.write_term(&quad.graph_name)?; Ok(()) } @@ -185,7 +168,7 @@ impl TermWriter for R { self.write_term(&quad.predicate)?; self.write_term(&quad.object)?; self.write_term(&quad.subject)?; - self.write_optional_term(&quad.graph_name)?; + self.write_term(&quad.graph_name)?; Ok(()) } @@ -193,7 +176,7 @@ impl TermWriter for R { self.write_term(&quad.object)?; self.write_term(&quad.subject)?; self.write_term(&quad.predicate)?; - self.write_optional_term(&quad.graph_name)?; + self.write_term(&quad.graph_name)?; Ok(()) } } @@ -252,8 +235,8 @@ impl Encoder { predicate: self.encode_named_node(quad.predicate())?, object: self.encode_term(quad.object())?, graph_name: match quad.graph_name() { - Some(graph_name) => Some(self.encode_named_or_blank_node(&graph_name)?), - None => None, + Some(graph_name) => self.encode_named_or_blank_node(&graph_name)?, + None => ENCODED_DEFAULT_GRAPH.clone(), }, }) } @@ -261,18 +244,19 @@ impl Encoder { pub fn encode_triple_in_graph( &self, triple: &Triple, - graph_name: Option, + graph_name: &EncodedTerm, ) -> Result { Ok(EncodedQuad { subject: self.encode_named_or_blank_node(triple.subject())?, predicate: self.encode_named_node(triple.predicate())?, object: self.encode_term(triple.object())?, - graph_name, + graph_name: graph_name.clone(), }) } pub fn decode_term(&self, encoded: &EncodedTerm) -> Result { match encoded { + EncodedTerm::DefaultGraph {} => Err("The default graph tag is not a valid term".into()), EncodedTerm::NamedNode { iri_id } => { Ok(NamedNode::from(self.decode_url_value(*iri_id)?).into()) } @@ -324,8 +308,8 @@ impl Encoder { self.decode_named_node(&encoded.predicate)?, self.decode_term(&encoded.object)?, match encoded.graph_name { - Some(ref graph_name) => Some(self.decode_named_or_blank_node(&graph_name)?), - None => None, + EncodedTerm::DefaultGraph {} => None, + ref graph_name => Some(self.decode_named_or_blank_node(graph_name)?), }, )) } diff --git a/src/store/rocksdb/storage.rs b/src/store/rocksdb/storage.rs index 327c0ea8..48770a0e 100644 --- a/src/store/rocksdb/storage.rs +++ b/src/store/rocksdb/storage.rs @@ -230,7 +230,7 @@ impl EncodedQuadsStore for RocksDbStore { fn quads_for_graph( &self, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result> { Ok(InGraphQuadsIterator { iter: self.quads()?, @@ -241,7 +241,7 @@ impl EncodedQuadsStore for RocksDbStore { fn quads_for_subject_graph( &self, subject: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result>> { Ok(InGraphQuadsIterator { iter: self.quads_for_subject(subject)?, @@ -253,7 +253,7 @@ impl EncodedQuadsStore for RocksDbStore { &self, subject: &EncodedTerm, predicate: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result>> { Ok(InGraphQuadsIterator { iter: self.quads_for_subject_predicate(subject, predicate)?, @@ -265,7 +265,7 @@ impl EncodedQuadsStore for RocksDbStore { &self, subject: &EncodedTerm, object: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result>> { Ok(InGraphQuadsIterator { iter: self.quads_for_subject_object(subject, object)?, @@ -276,7 +276,7 @@ impl EncodedQuadsStore for RocksDbStore { fn quads_for_predicate_graph( &self, predicate: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result>> { Ok(InGraphQuadsIterator { iter: self.quads_for_predicate(predicate)?, @@ -288,7 +288,7 @@ impl EncodedQuadsStore for RocksDbStore { &self, predicate: &EncodedTerm, object: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result>> { Ok(InGraphQuadsIterator { iter: self.quads_for_predicate_object(predicate, object)?, @@ -299,7 +299,7 @@ impl EncodedQuadsStore for RocksDbStore { fn quads_for_object_graph( &self, object: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result>> { Ok(InGraphQuadsIterator { iter: self.quads_for_object(object)?, @@ -363,7 +363,7 @@ struct EncodedQuadPattern { subject: Option, predicate: Option, object: Option, - graph_name: Option>, + graph_name: Option, } impl EncodedQuadPattern { @@ -371,7 +371,7 @@ impl EncodedQuadPattern { subject: Option, predicate: Option, object: Option, - graph_name: Option>, + graph_name: Option, ) -> Self { Self { subject, @@ -508,7 +508,7 @@ impl>> Iterator for FilteringEncodedQuads pub struct InGraphQuadsIterator>> { iter: I, - graph_name: Option, + graph_name: EncodedTerm, } impl>> Iterator for InGraphQuadsIterator { diff --git a/src/store/store.rs b/src/store/store.rs index 280d1610..56daa362 100644 --- a/src/store/store.rs +++ b/src/store/store.rs @@ -1,10 +1,7 @@ use errors::*; use model::*; use std::sync::Arc; -use store::numeric_encoder::BytesStore; -use store::numeric_encoder::EncodedQuad; -use store::numeric_encoder::EncodedTerm; -use store::numeric_encoder::Encoder; +use store::numeric_encoder::*; use store::Dataset; use store::Graph; use store::NamedGraph; @@ -60,42 +57,39 @@ pub trait EncodedQuadsStore: BytesStore + Sized { object: &EncodedTerm, ) -> Result; fn quads_for_object(&self, object: &EncodedTerm) -> Result; - fn quads_for_graph( - &self, - graph_name: &Option, - ) -> Result; + fn quads_for_graph(&self, graph_name: &EncodedTerm) -> Result; fn quads_for_subject_graph( &self, subject: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result; fn quads_for_subject_predicate_graph( &self, subject: &EncodedTerm, predicate: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result; fn quads_for_subject_object_graph( &self, subject: &EncodedTerm, object: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result; fn quads_for_predicate_graph( &self, predicate: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result; fn quads_for_predicate_object_graph( &self, predicate: &EncodedTerm, object: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result; fn quads_for_object_graph( &self, object: &EncodedTerm, - graph_name: &Option, + graph_name: &EncodedTerm, ) -> Result; fn contains(&self, quad: &EncodedQuad) -> Result; fn insert(&self, quad: &EncodedQuad) -> Result<()>; @@ -132,7 +126,7 @@ impl Dataset for StoreDataset { Ok(StoreNamedGraph { store: self.store.clone(), name: name.clone(), - encoded_name: Some(self.store.encoder().encode_named_or_blank_node(name)?), + encoded_name: self.store.encoder().encode_named_or_blank_node(name)?, }) } @@ -279,7 +273,7 @@ impl Dataset for StoreDataset { pub struct StoreNamedGraph { store: Arc, name: NamedOrBlankNode, - encoded_name: Option, + encoded_name: EncodedTerm, } impl Graph for StoreNamedGraph { @@ -390,7 +384,7 @@ impl Graph for StoreNamedGraph { &self .store .encoder() - .encode_triple_in_graph(triple, self.encoded_name.clone())?, + .encode_triple_in_graph(triple, &self.encoded_name)?, ) } @@ -399,7 +393,7 @@ impl Graph for StoreNamedGraph { &self .store .encoder() - .encode_triple_in_graph(triple, self.encoded_name.clone())?, + .encode_triple_in_graph(triple, &self.encoded_name)?, ) } @@ -408,7 +402,7 @@ impl Graph for StoreNamedGraph { &self .store .encoder() - .encode_triple_in_graph(triple, self.encoded_name.clone())?, + .encode_triple_in_graph(triple, &self.encoded_name)?, ) } @@ -448,7 +442,7 @@ impl Graph for StoreDefaultGraph { fn triples(&self) -> Result> { Ok(TriplesIterator { - iter: self.store.quads_for_graph(&None)?, + iter: self.store.quads_for_graph(&ENCODED_DEFAULT_GRAPH)?, store: self.store.clone(), }) } @@ -459,9 +453,10 @@ impl Graph for StoreDefaultGraph { ) -> Result> { let encoder = self.store.encoder(); Ok(TriplesIterator { - iter: self - .store - .quads_for_subject_graph(&encoder.encode_named_or_blank_node(subject)?, &None)?, + iter: self.store.quads_for_subject_graph( + &encoder.encode_named_or_blank_node(subject)?, + &ENCODED_DEFAULT_GRAPH, + )?, store: self.store.clone(), }) } @@ -475,7 +470,7 @@ impl Graph for StoreDefaultGraph { iter: self.store.quads_for_subject_predicate_graph( &encoder.encode_named_or_blank_node(subject)?, &encoder.encode_named_node(predicate)?, - &None, + &ENCODED_DEFAULT_GRAPH, )?, store: self.store.clone(), }) @@ -490,7 +485,7 @@ impl Graph for StoreDefaultGraph { iter: self.store.quads_for_subject_object_graph( &encoder.encode_named_or_blank_node(subject)?, &encoder.encode_term(object)?, - &None, + &ENCODED_DEFAULT_GRAPH, )?, store: self.store.clone(), }) @@ -501,9 +496,10 @@ impl Graph for StoreDefaultGraph { ) -> Result> { let encoder = self.store.encoder(); Ok(TriplesIterator { - iter: self - .store - .quads_for_predicate_graph(&encoder.encode_named_node(predicate)?, &None)?, + iter: self.store.quads_for_predicate_graph( + &encoder.encode_named_node(predicate)?, + &ENCODED_DEFAULT_GRAPH, + )?, store: self.store.clone(), }) } @@ -517,7 +513,7 @@ impl Graph for StoreDefaultGraph { iter: self.store.quads_for_predicate_object_graph( &encoder.encode_named_node(predicate)?, &encoder.encode_term(object)?, - &None, + &ENCODED_DEFAULT_GRAPH, )?, store: self.store.clone(), }) @@ -530,32 +526,47 @@ impl Graph for StoreDefaultGraph { Ok(TriplesIterator { iter: self .store - .quads_for_object_graph(&encoder.encode_term(object)?, &None)?, + .quads_for_object_graph(&encoder.encode_term(object)?, &ENCODED_DEFAULT_GRAPH)?, store: self.store.clone(), }) } fn contains(&self, triple: &Triple) -> Result { - self.store - .contains(&self.store.encoder().encode_triple_in_graph(triple, None)?) + self.store.contains( + &self + .store + .encoder() + .encode_triple_in_graph(triple, &ENCODED_DEFAULT_GRAPH)?, + ) } fn insert(&self, triple: &Triple) -> Result<()> { - self.store - .insert(&self.store.encoder().encode_triple_in_graph(triple, None)?) + self.store.insert( + &self + .store + .encoder() + .encode_triple_in_graph(triple, &ENCODED_DEFAULT_GRAPH)?, + ) } fn remove(&self, triple: &Triple) -> Result<()> { - self.store - .remove(&self.store.encoder().encode_triple_in_graph(triple, None)?) + self.store.remove( + &self + .store + .encoder() + .encode_triple_in_graph(triple, &ENCODED_DEFAULT_GRAPH)?, + ) } fn len(&self) -> Result { - Ok(self.store.quads_for_graph(&None)?.count()) + Ok(self.store.quads_for_graph(&ENCODED_DEFAULT_GRAPH)?.count()) } fn is_empty(&self) -> Result { - Ok(self.store.quads_for_graph(&None)?.any(|_| true)) + Ok(self + .store + .quads_for_graph(&ENCODED_DEFAULT_GRAPH)? + .any(|_| true)) } }