Avoids box in RocksStore.quads_for_pattern

pull/35/head
Tpt 4 years ago
parent fd4655b4e8
commit 8b88a7576c
  1. 26
      lib/src/store/numeric_encoder.rs
  2. 291
      lib/src/store/rocksdb.rs

@ -12,7 +12,7 @@ use siphasher::sip128::{Hasher128, SipHasher24};
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::Hash; use std::hash::Hash;
use std::hash::Hasher; use std::hash::Hasher;
use std::io::Read; use std::io::{Cursor, Read};
use std::mem::size_of; use std::mem::size_of;
use std::str; use std::str;
@ -800,6 +800,30 @@ pub fn write_gosp_quad(sink: &mut Vec<u8>, quad: &EncodedQuad) {
write_term(sink, quad.predicate); write_term(sink, quad.predicate);
} }
#[derive(Clone, Copy)]
pub enum QuadEncoding {
SPOG,
POSG,
OSPG,
GSPO,
GPOS,
GOSP,
}
impl QuadEncoding {
pub fn decode(self, buffer: &[u8]) -> Result<EncodedQuad> {
let mut cursor = Cursor::new(&buffer);
match self {
QuadEncoding::SPOG => cursor.read_spog_quad(),
QuadEncoding::POSG => cursor.read_posg_quad(),
QuadEncoding::OSPG => cursor.read_ospg_quad(),
QuadEncoding::GSPO => cursor.read_gspo_quad(),
QuadEncoding::GPOS => cursor.read_gpos_quad(),
QuadEncoding::GOSP => cursor.read_gosp_quad(),
}
}
}
pub trait StrLookup { pub trait StrLookup {
fn get_str(&self, id: StrHash) -> Result<Option<String>>; fn get_str(&self, id: StrHash) -> Result<Option<String>>;
} }

@ -2,10 +2,9 @@ use crate::model::*;
use crate::sparql::{GraphPattern, PreparedQuery, QueryOptions, SimplePreparedQuery}; use crate::sparql::{GraphPattern, PreparedQuery, QueryOptions, SimplePreparedQuery};
use crate::store::numeric_encoder::*; use crate::store::numeric_encoder::*;
use crate::store::{load_dataset, load_graph, ReadableEncodedStore, WritableEncodedStore}; use crate::store::{load_dataset, load_graph, ReadableEncodedStore, WritableEncodedStore};
use crate::{DatasetSyntax, Error, GraphSyntax, Result}; use crate::{DatasetSyntax, GraphSyntax, Result};
use rocksdb::*; use rocksdb::*;
use std::io::{BufRead, Cursor}; use std::io::BufRead;
use std::iter::{empty, once};
use std::mem::take; use std::mem::take;
use std::path::Path; use std::path::Path;
use std::str; use std::str;
@ -91,7 +90,7 @@ impl RocksDbStore {
db: Arc::new(DB::open_cf(&options, path, &COLUMN_FAMILIES)?), db: Arc::new(DB::open_cf(&options, path, &COLUMN_FAMILIES)?),
}; };
let mut transaction = new.handle()?.auto_transaction(); let mut transaction = new.handle().auto_transaction();
transaction.set_first_strings()?; transaction.set_first_strings()?;
transaction.commit()?; transaction.commit()?;
@ -128,7 +127,7 @@ impl RocksDbStore {
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>> + 'a
where where
Self: 'a, Self: 'a,
{ {
@ -136,16 +135,15 @@ impl RocksDbStore {
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( self.handle()
self.encoded_quads_for_pattern(subject, predicate, object, graph_name) .encoded_quads_for_pattern(subject, predicate, object, graph_name)
.map(move |quad| self.decode_quad(&quad?)), .map(move |quad| self.decode_quad(&quad?))
)
} }
/// Checks if this store contains a given quad /// Checks if this store contains a given quad
pub fn contains(&self, quad: &Quad) -> Result<bool> { pub fn contains(&self, quad: &Quad) -> Result<bool> {
let quad = quad.into(); let quad = quad.into();
self.handle()?.contains(&quad) self.handle().contains(&quad)
} }
/// Executes a transaction. /// Executes a transaction.
@ -158,7 +156,7 @@ impl RocksDbStore {
&'a self, &'a self,
f: impl FnOnce(&mut RocksDbTransaction<'a>) -> Result<()>, f: impl FnOnce(&mut RocksDbTransaction<'a>) -> Result<()>,
) -> Result<()> { ) -> Result<()> {
let mut transaction = self.handle()?.transaction(); let mut transaction = self.handle().transaction();
f(&mut transaction)?; f(&mut transaction)?;
transaction.commit() transaction.commit()
} }
@ -176,7 +174,7 @@ impl RocksDbStore {
to_graph_name: Option<&NamedOrBlankNode>, to_graph_name: Option<&NamedOrBlankNode>,
base_iri: Option<&str>, base_iri: Option<&str>,
) -> Result<()> { ) -> Result<()> {
let mut transaction = self.handle()?.auto_transaction(); let mut transaction = self.handle().auto_transaction();
load_graph(&mut transaction, reader, syntax, to_graph_name, base_iri)?; load_graph(&mut transaction, reader, syntax, to_graph_name, base_iri)?;
transaction.commit() transaction.commit()
} }
@ -193,14 +191,14 @@ impl RocksDbStore {
syntax: DatasetSyntax, syntax: DatasetSyntax,
base_iri: Option<&str>, base_iri: Option<&str>,
) -> Result<()> { ) -> Result<()> {
let mut transaction = self.handle()?.auto_transaction(); let mut transaction = self.handle().auto_transaction();
load_dataset(&mut transaction, reader, syntax, base_iri)?; load_dataset(&mut transaction, reader, syntax, base_iri)?;
transaction.commit() transaction.commit()
} }
/// Adds a quad to this store. /// Adds a quad to this store.
pub fn insert(&self, quad: &Quad) -> Result<()> { pub fn insert(&self, quad: &Quad) -> Result<()> {
let mut transaction = self.handle()?.auto_transaction(); let mut transaction = self.handle().auto_transaction();
let quad = transaction.encode_quad(quad)?; let quad = transaction.encode_quad(quad)?;
transaction.insert_encoded(&quad)?; transaction.insert_encoded(&quad)?;
transaction.commit() transaction.commit()
@ -208,23 +206,23 @@ impl RocksDbStore {
/// Removes a quad from this store. /// Removes a quad from this store.
pub fn remove(&self, quad: &Quad) -> Result<()> { pub fn remove(&self, quad: &Quad) -> Result<()> {
let mut transaction = self.handle()?.auto_transaction(); let mut transaction = self.handle().auto_transaction();
let quad = quad.into(); let quad = quad.into();
transaction.remove_encoded(&quad)?; transaction.remove_encoded(&quad)?;
transaction.commit() transaction.commit()
} }
fn handle<'a>(&'a self) -> Result<RocksDbStoreHandle<'a>> { fn handle(&self) -> RocksDbStoreHandle<'_> {
Ok(RocksDbStoreHandle { RocksDbStoreHandle {
db: &self.db, db: &self.db,
id2str_cf: get_cf(&self.db, ID2STR_CF)?, id2str_cf: get_cf(&self.db, ID2STR_CF),
spog_cf: get_cf(&self.db, SPOG_CF)?, spog_cf: get_cf(&self.db, SPOG_CF),
posg_cf: get_cf(&self.db, POSG_CF)?, posg_cf: get_cf(&self.db, POSG_CF),
ospg_cf: get_cf(&self.db, OSPG_CF)?, ospg_cf: get_cf(&self.db, OSPG_CF),
gspo_cf: get_cf(&self.db, GSPO_CF)?, gspo_cf: get_cf(&self.db, GSPO_CF),
gpos_cf: get_cf(&self.db, GPOS_CF)?, gpos_cf: get_cf(&self.db, GPOS_CF),
gosp_cf: get_cf(&self.db, GOSP_CF)?, gosp_cf: get_cf(&self.db, GOSP_CF),
}) }
} }
} }
@ -232,7 +230,7 @@ impl StrLookup for RocksDbStore {
fn get_str(&self, id: StrHash) -> Result<Option<String>> { fn get_str(&self, id: StrHash) -> Result<Option<String>> {
Ok(self Ok(self
.db .db
.get_cf(get_cf(&self.db, ID2STR_CF)?, &id.to_be_bytes())? .get_cf(get_cf(&self.db, ID2STR_CF), &id.to_be_bytes())?
.map(String::from_utf8) .map(String::from_utf8)
.transpose()?) .transpose()?)
} }
@ -246,116 +244,108 @@ impl ReadableEncodedStore for RocksDbStore {
object: Option<EncodedTerm>, object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>, graph_name: Option<EncodedTerm>,
) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a> { ) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a> {
let handle = match self.handle() { Box::new(
Ok(handle) => handle, self.handle()
Err(error) => return Box::new(once(Err(error))), .encoded_quads_for_pattern(subject, predicate, object, graph_name),
}; )
}
}
impl<'a> RocksDbStoreHandle<'a> {
fn transaction(&self) -> RocksDbTransaction<'a> {
RocksDbTransaction {
inner: RocksDbInnerTransaction {
handle: self.clone(),
batch: WriteBatch::default(),
buffer: Vec::default(),
},
}
}
fn auto_transaction(&self) -> RocksDbAutoTransaction<'a> {
RocksDbAutoTransaction {
inner: RocksDbInnerTransaction {
handle: self.clone(),
batch: WriteBatch::default(),
buffer: Vec::default(),
},
}
}
fn contains(&self, quad: &EncodedQuad) -> Result<bool> {
let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE);
write_spog_quad(&mut buffer, quad);
Ok(self.db.get_pinned_cf(self.spog_cf, &buffer)?.is_some())
}
fn encoded_quads_for_pattern(
&self,
subject: Option<EncodedTerm>,
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
) -> DecodingIndexIterator<'a> {
match subject { match subject {
Some(subject) => match predicate { Some(subject) => match predicate {
Some(predicate) => match object { Some(predicate) => match object {
Some(object) => match graph_name { Some(object) => match graph_name {
Some(graph_name) => { Some(graph_name) => self
let quad = EncodedQuad::new(subject, predicate, object, graph_name); .spog_quads(encode_term_quad(subject, predicate, object, graph_name)),
match handle.contains(&quad) { None => self.quads_for_subject_predicate_object(subject, predicate, object),
Ok(true) => Box::new(once(Ok(quad))),
Ok(false) => Box::new(empty()),
Err(error) => Box::new(once(Err(error))),
}
}
None => Box::new(
handle.quads_for_subject_predicate_object(subject, predicate, object),
),
}, },
None => match graph_name { None => match graph_name {
Some(graph_name) => Box::new( Some(graph_name) => {
handle self.quads_for_subject_predicate_graph(subject, predicate, graph_name)
.quads_for_subject_predicate_graph(subject, predicate, graph_name), }
), None => self.quads_for_subject_predicate(subject, predicate),
None => Box::new(handle.quads_for_subject_predicate(subject, predicate)),
}, },
}, },
None => match object { None => match object {
Some(object) => match graph_name { Some(object) => match graph_name {
Some(graph_name) => Box::new(
handle.quads_for_subject_object_graph(subject, object, graph_name),
),
None => Box::new(handle.quads_for_subject_object(subject, object)),
},
None => match graph_name {
Some(graph_name) => { Some(graph_name) => {
Box::new(handle.quads_for_subject_graph(subject, graph_name)) self.quads_for_subject_object_graph(subject, object, graph_name)
} }
None => Box::new(handle.quads_for_subject(subject)), None => self.quads_for_subject_object(subject, object),
},
None => match graph_name {
Some(graph_name) => self.quads_for_subject_graph(subject, graph_name),
None => self.quads_for_subject(subject),
}, },
}, },
}, },
None => match predicate { None => match predicate {
Some(predicate) => match object { Some(predicate) => match object {
Some(object) => match graph_name { Some(object) => match graph_name {
Some(graph_name) => Box::new(
handle.quads_for_predicate_object_graph(predicate, object, graph_name),
),
None => Box::new(handle.quads_for_predicate_object(predicate, object)),
},
None => match graph_name {
Some(graph_name) => { Some(graph_name) => {
Box::new(handle.quads_for_predicate_graph(predicate, graph_name)) self.quads_for_predicate_object_graph(predicate, object, graph_name)
} }
None => Box::new(handle.quads_for_predicate(predicate)),
None => self.quads_for_predicate_object(predicate, object),
},
None => match graph_name {
Some(graph_name) => self.quads_for_predicate_graph(predicate, graph_name),
None => self.quads_for_predicate(predicate),
}, },
}, },
None => match object { None => match object {
Some(object) => match graph_name { Some(object) => match graph_name {
Some(graph_name) => { Some(graph_name) => self.quads_for_object_graph(object, graph_name),
Box::new(handle.quads_for_object_graph(object, graph_name)) None => self.quads_for_object(object),
}
None => Box::new(handle.quads_for_object(object)),
}, },
None => match graph_name { None => match graph_name {
Some(graph_name) => Box::new(handle.quads_for_graph(graph_name)), Some(graph_name) => self.quads_for_graph(graph_name),
None => Box::new(handle.quads()), None => self.quads(),
}, },
}, },
}, },
} }
} }
}
impl<'a> RocksDbStoreHandle<'a> { fn quads(&self) -> DecodingIndexIterator<'a> {
fn transaction(&self) -> RocksDbTransaction<'a> {
RocksDbTransaction {
inner: RocksDbInnerTransaction {
handle: self.clone(),
batch: WriteBatch::default(),
buffer: Vec::default(),
},
}
}
fn auto_transaction(&self) -> RocksDbAutoTransaction<'a> {
RocksDbAutoTransaction {
inner: RocksDbInnerTransaction {
handle: self.clone(),
batch: WriteBatch::default(),
buffer: Vec::default(),
},
}
}
fn contains(&self, quad: &EncodedQuad) -> Result<bool> {
let mut buffer = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE);
write_spog_quad(&mut buffer, quad);
Ok(self.db.get_pinned_cf(self.spog_cf, &buffer)?.is_some())
}
fn quads(&self) -> impl Iterator<Item = Result<EncodedQuad>> + 'a {
self.spog_quads(Vec::default()) self.spog_quads(Vec::default())
} }
fn quads_for_subject( fn quads_for_subject(&self, subject: EncodedTerm) -> DecodingIndexIterator<'a> {
&self,
subject: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a {
self.spog_quads(encode_term(subject)) self.spog_quads(encode_term(subject))
} }
@ -363,7 +353,7 @@ impl<'a> RocksDbStoreHandle<'a> {
&self, &self,
subject: EncodedTerm, subject: EncodedTerm,
predicate: EncodedTerm, predicate: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.spog_quads(encode_term_pair(subject, predicate)) self.spog_quads(encode_term_pair(subject, predicate))
} }
@ -372,7 +362,7 @@ impl<'a> RocksDbStoreHandle<'a> {
subject: EncodedTerm, subject: EncodedTerm,
predicate: EncodedTerm, predicate: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.spog_quads(encode_term_triple(subject, predicate, object)) self.spog_quads(encode_term_triple(subject, predicate, object))
} }
@ -380,14 +370,11 @@ impl<'a> RocksDbStoreHandle<'a> {
&self, &self,
subject: EncodedTerm, subject: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.ospg_quads(encode_term_pair(object, subject)) self.ospg_quads(encode_term_pair(object, subject))
} }
fn quads_for_predicate( fn quads_for_predicate(&self, predicate: EncodedTerm) -> DecodingIndexIterator<'a> {
&self,
predicate: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a {
self.posg_quads(encode_term(predicate)) self.posg_quads(encode_term(predicate))
} }
@ -395,21 +382,15 @@ impl<'a> RocksDbStoreHandle<'a> {
&self, &self,
predicate: EncodedTerm, predicate: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.posg_quads(encode_term_pair(predicate, object)) self.posg_quads(encode_term_pair(predicate, object))
} }
fn quads_for_object( fn quads_for_object(&self, object: EncodedTerm) -> DecodingIndexIterator<'a> {
&self,
object: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a {
self.ospg_quads(encode_term(object)) self.ospg_quads(encode_term(object))
} }
fn quads_for_graph( fn quads_for_graph(&self, graph_name: EncodedTerm) -> DecodingIndexIterator<'a> {
&self,
graph_name: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a {
self.gspo_quads(encode_term(graph_name)) self.gspo_quads(encode_term(graph_name))
} }
@ -417,7 +398,7 @@ impl<'a> RocksDbStoreHandle<'a> {
&self, &self,
subject: EncodedTerm, subject: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.gspo_quads(encode_term_pair(graph_name, subject)) self.gspo_quads(encode_term_pair(graph_name, subject))
} }
@ -426,7 +407,7 @@ impl<'a> RocksDbStoreHandle<'a> {
subject: EncodedTerm, subject: EncodedTerm,
predicate: EncodedTerm, predicate: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.gspo_quads(encode_term_triple(graph_name, subject, predicate)) self.gspo_quads(encode_term_triple(graph_name, subject, predicate))
} }
@ -435,7 +416,7 @@ impl<'a> RocksDbStoreHandle<'a> {
subject: EncodedTerm, subject: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.gosp_quads(encode_term_triple(graph_name, object, subject)) self.gosp_quads(encode_term_triple(graph_name, object, subject))
} }
@ -443,7 +424,7 @@ impl<'a> RocksDbStoreHandle<'a> {
&self, &self,
predicate: EncodedTerm, predicate: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.gpos_quads(encode_term_pair(graph_name, predicate)) self.gpos_quads(encode_term_pair(graph_name, predicate))
} }
@ -452,7 +433,7 @@ impl<'a> RocksDbStoreHandle<'a> {
predicate: EncodedTerm, predicate: EncodedTerm,
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.gpos_quads(encode_term_triple(graph_name, predicate, object)) self.gpos_quads(encode_term_triple(graph_name, predicate, object))
} }
@ -460,58 +441,46 @@ impl<'a> RocksDbStoreHandle<'a> {
&self, &self,
object: EncodedTerm, object: EncodedTerm,
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
self.gosp_quads(encode_term_pair(graph_name, object)) self.gosp_quads(encode_term_pair(graph_name, object))
} }
fn spog_quads(&self, prefix: Vec<u8>) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { fn spog_quads(&self, prefix: Vec<u8>) -> DecodingIndexIterator<'a> {
self.inner_quads(self.spog_cf, prefix, |buffer| { self.inner_quads(self.spog_cf, prefix, QuadEncoding::SPOG)
Cursor::new(buffer).read_spog_quad()
})
} }
fn posg_quads(&self, prefix: Vec<u8>) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { fn posg_quads(&self, prefix: Vec<u8>) -> DecodingIndexIterator<'a> {
self.inner_quads(self.posg_cf, prefix, |buffer| { self.inner_quads(self.posg_cf, prefix, QuadEncoding::POSG)
Cursor::new(buffer).read_posg_quad()
})
} }
fn ospg_quads(&self, prefix: Vec<u8>) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { fn ospg_quads(&self, prefix: Vec<u8>) -> DecodingIndexIterator<'a> {
self.inner_quads(self.ospg_cf, prefix, |buffer| { self.inner_quads(self.ospg_cf, prefix, QuadEncoding::OSPG)
Cursor::new(buffer).read_ospg_quad()
})
} }
fn gspo_quads(&self, prefix: Vec<u8>) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { fn gspo_quads(&self, prefix: Vec<u8>) -> DecodingIndexIterator<'a> {
self.inner_quads(self.gspo_cf, prefix, |buffer| { self.inner_quads(self.gspo_cf, prefix, QuadEncoding::GSPO)
Cursor::new(buffer).read_gspo_quad()
})
} }
fn gpos_quads(&self, prefix: Vec<u8>) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { fn gpos_quads(&self, prefix: Vec<u8>) -> DecodingIndexIterator<'a> {
self.inner_quads(self.gpos_cf, prefix, |buffer| { self.inner_quads(self.gpos_cf, prefix, QuadEncoding::GPOS)
Cursor::new(buffer).read_gpos_quad()
})
} }
fn gosp_quads(&self, prefix: Vec<u8>) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { fn gosp_quads(&self, prefix: Vec<u8>) -> DecodingIndexIterator<'a> {
self.inner_quads(self.gosp_cf, prefix, |buffer| { self.inner_quads(self.gosp_cf, prefix, QuadEncoding::GOSP)
Cursor::new(buffer).read_gosp_quad()
})
} }
fn inner_quads( fn inner_quads(
&self, &self,
cf: &ColumnFamily, cf: &ColumnFamily,
prefix: Vec<u8>, prefix: Vec<u8>,
decode: impl Fn(&[u8]) -> Result<EncodedQuad> + 'a, encoding: QuadEncoding,
) -> impl Iterator<Item = Result<EncodedQuad>> + 'a { ) -> DecodingIndexIterator<'a> {
let mut iter = self.db.raw_iterator_cf(cf); let mut iter = self.db.raw_iterator_cf(cf);
iter.seek(&prefix); iter.seek(&prefix);
DecodingIndexIterator { DecodingIndexIterator {
iter, iter,
prefix, prefix,
decode, encoding,
} }
} }
} }
@ -699,9 +668,10 @@ impl RocksDbInnerTransaction<'_> {
} }
} }
fn get_cf<'a>(db: &'a DB, name: &str) -> Result<&'a ColumnFamily> { #[allow(clippy::option_expect_used)]
fn get_cf<'a>(db: &'a DB, name: &str) -> &'a ColumnFamily {
db.cf_handle(name) db.cf_handle(name)
.ok_or_else(|| Error::msg(format!("column family {} not found", name))) .expect("A column family that should exists in RocksDB does not exists")
} }
fn encode_term(t: EncodedTerm) -> Vec<u8> { fn encode_term(t: EncodedTerm) -> Vec<u8> {
@ -725,19 +695,28 @@ fn encode_term_triple(t1: EncodedTerm, t2: EncodedTerm, t3: EncodedTerm) -> Vec<
vec vec
} }
struct DecodingIndexIterator<'a, F: Fn(&[u8]) -> Result<EncodedQuad>> { fn encode_term_quad(t1: EncodedTerm, t2: EncodedTerm, t3: EncodedTerm, t4: EncodedTerm) -> Vec<u8> {
let mut vec = Vec::with_capacity(4 * WRITTEN_TERM_MAX_SIZE);
write_term(&mut vec, t1);
write_term(&mut vec, t2);
write_term(&mut vec, t3);
write_term(&mut vec, t4);
vec
}
struct DecodingIndexIterator<'a> {
iter: DBRawIterator<'a>, iter: DBRawIterator<'a>,
prefix: Vec<u8>, prefix: Vec<u8>,
decode: F, encoding: QuadEncoding,
} }
impl<'a, F: Fn(&[u8]) -> Result<EncodedQuad>> Iterator for DecodingIndexIterator<'a, F> { impl<'a> Iterator for DecodingIndexIterator<'a> {
type Item = Result<EncodedQuad>; type Item = Result<EncodedQuad>;
fn next(&mut self) -> Option<Result<EncodedQuad>> { fn next(&mut self) -> Option<Result<EncodedQuad>> {
if let Some(key) = self.iter.key() { if let Some(key) = self.iter.key() {
if key.starts_with(&self.prefix) { if key.starts_with(&self.prefix) {
let result = (self.decode)(key); let result = self.encoding.decode(key);
self.iter.next(); self.iter.next();
Some(result) Some(result)
} else { } else {

Loading…
Cancel
Save