Borrow as much as possible in Insert

This commit is contained in:
asonix 2023-05-15 15:40:34 -05:00
parent b2e96fc1ae
commit 314c588562
3 changed files with 55 additions and 43 deletions

View file

@ -45,50 +45,50 @@ impl Handler<InsertTriples> for TripleHandler {
}
#[derive(Default)]
struct StartInsertState {
iris: HashSet<iref::IriBuf>,
blank_nodes: HashSet<rdf_types::BlankIdBuf>,
strings: HashSet<String>,
langtags: HashSet<langtag::LanguageTagBuf>,
struct StartInsertState<'a> {
iris: HashSet<&'a iref::IriBuf>,
blank_nodes: HashSet<&'a rdf_types::BlankIdBuf>,
strings: HashSet<&'a str>,
langtags: HashSet<&'a langtag::LanguageTagBuf>,
}
struct InsertState {
iris: HashMap<iref::IriBuf, u128>,
blank_nodes: HashMap<rdf_types::BlankIdBuf, u128>,
strings: HashMap<String, u128>,
langtags: HashMap<langtag::LanguageTagBuf, u128>,
struct InsertState<'a> {
iris: HashMap<&'a iref::IriBuf, u128>,
blank_nodes: HashMap<&'a rdf_types::BlankIdBuf, u128>,
strings: HashMap<&'a str, u128>,
langtags: HashMap<&'a langtag::LanguageTagBuf, u128>,
}
impl StartInsertState {
fn from_triples(triples: &[Triple]) -> Self {
impl<'a> StartInsertState<'a> {
fn from_triples(triples: &'a [Triple]) -> Self {
triples.iter().fold(Self::default(), Self::add_triple)
}
fn add_triple(mut self, triple: &Triple) -> Self {
fn add_triple(mut self, triple: &'a Triple) -> Self {
match &triple.subject.0 {
rdf_types::Subject::Iri(iri) => self.iris.insert(iri.clone()),
rdf_types::Subject::Blank(blank) => self.blank_nodes.insert(blank.clone()),
rdf_types::Subject::Iri(iri) => self.iris.insert(iri),
rdf_types::Subject::Blank(blank) => self.blank_nodes.insert(blank),
};
self.iris.insert(triple.predicate.0.clone());
self.iris.insert(&triple.predicate.0);
match &triple.object.0 {
rdf_types::Object::Id(rdf_types::Id::Iri(iri)) => {
self.iris.insert(iri.clone());
self.iris.insert(iri);
}
rdf_types::Object::Id(rdf_types::Id::Blank(blank)) => {
self.blank_nodes.insert(blank.clone());
self.blank_nodes.insert(blank);
}
rdf_types::Object::Literal(rdf_types::Literal::String(s)) => {
self.strings.insert(s.clone());
self.strings.insert(s);
}
rdf_types::Object::Literal(rdf_types::Literal::TypedString(s, iri)) => {
self.strings.insert(s.clone());
self.iris.insert(iri.clone());
self.strings.insert(s);
self.iris.insert(iri);
}
rdf_types::Object::Literal(rdf_types::Literal::LangString(s, langtag)) => {
self.strings.insert(s.clone());
self.langtags.insert(langtag.clone());
self.strings.insert(s);
self.langtags.insert(langtag);
}
};
@ -98,7 +98,7 @@ impl StartInsertState {
async fn insert_related<C: AsyncConnection>(
self,
connection: &C,
) -> Result<InsertState, bonsaidb::core::Error> {
) -> Result<InsertState<'a>, bonsaidb::core::Error> {
let iris = self.insert_iris(connection).await?;
let blank_nodes = self.generate_blank_nodes(connection).await?;
let strings = self.insert_strings(connection).await?;
@ -115,17 +115,15 @@ impl StartInsertState {
async fn insert_iris<C: AsyncConnection>(
&self,
connection: &C,
) -> Result<HashMap<iref::IriBuf, u128>, bonsaidb::core::Error> {
) -> Result<HashMap<&'a iref::IriBuf, u128>, bonsaidb::core::Error> {
// TODO: Batch
let mut ids = HashMap::with_capacity(self.iris.len());
for iri in &self.iris {
// TODO: handle duplicate record
let res = crate::schema::Iri {
iri: iri.clone().into(),
}
.push_into_async(connection)
.await;
let res = crate::schema::Iri { iri: (*iri).into() }
.push_into_async(connection)
.await;
let id = match res {
Ok(doc) => doc.header.id,
@ -139,7 +137,7 @@ impl StartInsertState {
Err(e) => return Err(e.into()),
};
ids.insert(iri.clone(), id);
ids.insert(*iri, id);
}
Ok(ids)
@ -148,13 +146,13 @@ impl StartInsertState {
async fn insert_strings<C: AsyncConnection>(
&self,
connection: &C,
) -> Result<HashMap<String, u128>, bonsaidb::core::Error> {
) -> Result<HashMap<&'a str, u128>, bonsaidb::core::Error> {
// TODO: Batch
let mut strings = HashMap::with_capacity(self.strings.len());
for string in &self.strings {
let res = crate::schema::LiteralString {
string: string.clone(),
string: (*string).into(),
}
.push_into_async(connection)
.await;
@ -171,7 +169,7 @@ impl StartInsertState {
Err(e) => return Err(e.into()),
};
strings.insert(string.clone(), id);
strings.insert(*string, id);
}
Ok(strings)
@ -180,13 +178,13 @@ impl StartInsertState {
async fn insert_langtags<C: AsyncConnection>(
&self,
connection: &C,
) -> Result<HashMap<langtag::LanguageTagBuf, u128>, bonsaidb::core::Error> {
) -> Result<HashMap<&'a langtag::LanguageTagBuf, u128>, bonsaidb::core::Error> {
// TODO: Batch
let mut langtags = HashMap::with_capacity(self.langtags.len());
for langtag in &self.langtags {
let res = crate::schema::LiteralLanguageTag {
langtag: langtag.clone().into(),
langtag: (*langtag).into(),
}
.push_into_async(connection)
.await;
@ -203,7 +201,7 @@ impl StartInsertState {
Err(e) => return Err(e.into()),
};
langtags.insert(langtag.clone(), id);
langtags.insert(*langtag, id);
}
Ok(langtags)
@ -212,21 +210,21 @@ impl StartInsertState {
async fn generate_blank_nodes<C: AsyncConnection>(
&self,
connection: &C,
) -> Result<HashMap<rdf_types::BlankIdBuf, u128>, bonsaidb::core::Error> {
) -> Result<HashMap<&'a rdf_types::BlankIdBuf, u128>, bonsaidb::core::Error> {
// TODO: Batch
let mut blank_nodes = HashMap::with_capacity(self.blank_nodes.len());
for blank_node in &self.blank_nodes {
let doc = crate::schema::BlankId.push_into_async(connection).await?;
blank_nodes.insert(blank_node.clone(), doc.header.id);
blank_nodes.insert(*blank_node, doc.header.id);
}
Ok(blank_nodes)
}
}
impl InsertState {
impl<'a> InsertState<'a> {
fn translate_triples(&self, triples: &[Triple]) -> Vec<crate::schema::Triple> {
triples
.iter()
@ -252,17 +250,19 @@ impl InsertState {
)
}
rdf_types::Term::Literal(rdf_types::Literal::String(s)) => {
crate::schema::Object::String(*self.strings.get(s).expect("String exists"))
crate::schema::Object::String(
*self.strings.get(s.as_str()).expect("String exists"),
)
}
rdf_types::Term::Literal(rdf_types::Literal::TypedString(s, iri)) => {
crate::schema::Object::TypedString {
string: *self.strings.get(s).expect("String exists"),
string: *self.strings.get(s.as_str()).expect("String exists"),
iri: *self.iris.get(iri).expect("Iri exists"),
}
}
rdf_types::Term::Literal(rdf_types::Literal::LangString(s, langtag)) => {
crate::schema::Object::LangString {
string: *self.strings.get(s).expect("String exists"),
string: *self.strings.get(s.as_str()).expect("String exists"),
langtag: *self.langtags.get(langtag).expect("Langtag exists"),
}
}

View file

@ -40,6 +40,12 @@ impl From<iref::IriBuf> for Iri<'static> {
}
}
impl<'a> From<&'a iref::IriBuf> for OwnedIri {
fn from(value: &'a iref::IriBuf) -> Self {
Self(Iri::from(value).into_owned())
}
}
impl From<iref::IriBuf> for OwnedIri {
fn from(value: iref::IriBuf) -> Self {
Self(value.into())

View file

@ -42,6 +42,12 @@ impl From<langtag::LanguageTagBuf> for LanguageTag<'static> {
}
}
impl<'a> From<&'a langtag::LanguageTagBuf> for OwnedLanguageTag {
fn from(value: &'a langtag::LanguageTagBuf) -> Self {
Self(LanguageTag::from(value).into_owned())
}
}
impl From<langtag::LanguageTagBuf> for OwnedLanguageTag {
fn from(value: langtag::LanguageTagBuf) -> Self {
Self(value.into())