From 76507623ac76cfe0f8d6d4fee127d9f6a62fb0df Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Mon, 2 Jul 2018 10:33:43 -0700 Subject: [PATCH] Part 4: Prepare EDN `Entity` type for interning tempids during parsing. This is all part of moving the entity builder away from building term instances and toward building entity instances. One of the nice things that the existing term interface does is allow consumers to use lightweight reference counted tempid handles; I don't want to lose that, so we'll build it into the entity data structures directly. --- db/src/internal_types.rs | 8 ++++---- db/src/tx.rs | 17 ++++++----------- edn/src/edn.rustpeg | 2 +- edn/src/entities.rs | 8 ++++++-- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/db/src/internal_types.rs b/db/src/internal_types.rs index 9e323d61..782ff22d 100644 --- a/db/src/internal_types.rs +++ b/db/src/internal_types.rs @@ -72,7 +72,7 @@ impl TransactableValue for ValueAndSpan { bail!(DbErrorKind::InputError(errors::InputError::BadEntityPlace)) } }, - Text(v) => Ok(EntityPlace::TempId(TempId::External(v))), + Text(v) => Ok(EntityPlace::TempId(TempId::External(v).into())), List(ls) => { let mut it = ls.iter(); match (it.next().map(|x| &x.inner), it.next(), it.next(), it.next()) { @@ -107,7 +107,7 @@ impl TransactableValue for ValueAndSpan { } fn as_tempid(&self) -> Option { - self.inner.as_text().cloned().map(TempId::External) + self.inner.as_text().cloned().map(TempId::External).map(|v| v.into()) } } @@ -123,7 +123,7 @@ impl TransactableValue for TypedValue { match self { TypedValue::Ref(x) => Ok(EntityPlace::Entid(entities::EntidOrIdent::Entid(x))), TypedValue::Keyword(x) => Ok(EntityPlace::Entid(entities::EntidOrIdent::Ident((*x).clone()))), - TypedValue::String(x) => Ok(EntityPlace::TempId(TempId::External((*x).clone()))), + TypedValue::String(x) => Ok(EntityPlace::TempId(TempId::External((*x).clone()).into())), TypedValue::Boolean(_) | TypedValue::Long(_) | TypedValue::Double(_) | @@ -134,7 +134,7 @@ impl TransactableValue for TypedValue { fn as_tempid(&self) -> Option { match self { - &TypedValue::String(ref s) => Some(TempId::External((**s).clone())), + &TypedValue::String(ref s) => Some(TempId::External((**s).clone()).into()), _ => None, } } diff --git a/db/src/tx.rs b/db/src/tx.rs index 46dd41d7..a398b114 100644 --- a/db/src/tx.rs +++ b/db/src/tx.rs @@ -65,7 +65,6 @@ use db::{ use edn::{ InternSet, Keyword, - ValueRc, }; use entids; use errors; @@ -301,15 +300,11 @@ impl<'conn, 'a, W> Tx<'conn, 'a, W> where W: TransactWatcher { Ok(self.lookup_refs.intern((lr_a, lr_typed_value))) } - fn intern_temp_id(&mut self, temp_id: TempId) -> ValueRc { - self.temp_ids.intern(temp_id) - } - /// Allocate private internal tempids reserved for Mentat. Internal tempids just need to be /// unique within one transaction; they should never escape a transaction. fn allocate_mentat_id(&mut self) -> entmod::EntityPlace { self.mentat_id_count += 1; - entmod::EntityPlace::TempId(TempId::Internal(self.mentat_id_count)) + entmod::EntityPlace::TempId(TempId::Internal(self.mentat_id_count).into()) } fn entity_e_into_term_e(&mut self, x: entmod::EntityPlace) -> Result> { @@ -323,7 +318,7 @@ impl<'conn, 'a, W> Tx<'conn, 'a, W> where W: TransactWatcher { }, entmod::EntityPlace::TempId(e) => { - Ok(Either::Right(LookupRefOrTempId::TempId(self.intern_temp_id(e)))) + Ok(Either::Right(LookupRefOrTempId::TempId(self.temp_ids.intern(e)))) }, entmod::EntityPlace::LookupRef(ref lookup_ref) => { @@ -369,7 +364,7 @@ impl<'conn, 'a, W> Tx<'conn, 'a, W> where W: TransactWatcher { // that the given value is in the attribute's value set, or (in // limited cases) coerce the value into the attribute's value set. match v.as_tempid() { - Some(tempid) => Ok(Either::Right(LookupRefOrTempId::TempId(self.intern_temp_id(tempid)))), + Some(tempid) => Ok(Either::Right(LookupRefOrTempId::TempId(self.temp_ids.intern(tempid)))), None => { if let TypedValue::Ref(entid) = v.into_typed_value(&self.schema, ValueType::Ref)? { Ok(Either::Left(KnownEntid(entid))) @@ -385,7 +380,7 @@ impl<'conn, 'a, W> Tx<'conn, 'a, W> where W: TransactWatcher { Ok(Either::Left(KnownEntid(self.entity_a_into_term_a(entid)?))), entmod::ValuePlace::TempId(tempid) => - Ok(Either::Right(LookupRefOrTempId::TempId(self.intern_temp_id(tempid)))), + Ok(Either::Right(LookupRefOrTempId::TempId(self.temp_ids.intern(tempid)))), entmod::ValuePlace::LookupRef(ref lookup_ref) => Ok(Either::Right(LookupRefOrTempId::LookupRef(self.intern_lookup_ref(lookup_ref)?))), @@ -456,7 +451,7 @@ impl<'conn, 'a, W> Tx<'conn, 'a, W> where W: TransactWatcher { // limited cases) coerce the value into the attribute's value set. if attribute.value_type == ValueType::Ref { match v.as_tempid() { - Some(tempid) => Either::Right(LookupRefOrTempId::TempId(in_process.intern_temp_id(tempid))), + Some(tempid) => Either::Right(LookupRefOrTempId::TempId(in_process.temp_ids.intern(tempid))), None => v.into_typed_value(&self.schema, attribute.value_type).map(Either::Left)?, } } else { @@ -468,7 +463,7 @@ impl<'conn, 'a, W> Tx<'conn, 'a, W> where W: TransactWatcher { Either::Left(TypedValue::Ref(in_process.entity_a_into_term_a(entid)?)), entmod::ValuePlace::TempId(tempid) => - Either::Right(LookupRefOrTempId::TempId(in_process.intern_temp_id(tempid))), + Either::Right(LookupRefOrTempId::TempId(in_process.temp_ids.intern(tempid))), entmod::ValuePlace::LookupRef(ref lookup_ref) => { if attribute.value_type != ValueType::Ref { diff --git a/edn/src/edn.rustpeg b/edn/src/edn.rustpeg index 21926b1f..2a642bea 100644 --- a/edn/src/edn.rustpeg +++ b/edn/src/edn.rustpeg @@ -260,7 +260,7 @@ tx_function -> TxFunction = "(" __ n:$(symbol_name) __ ")" { TxFunction { op: PlainSymbol::plain(n) } } entity_place -> EntityPlace - = v:raw_text { EntityPlace::TempId(TempId::External(v)) } + = v:raw_text { EntityPlace::TempId(TempId::External(v).into()) } / v:entid { EntityPlace::Entid(v) } / v:lookup_ref { EntityPlace::LookupRef(v) } / v:tx_function { EntityPlace::TxFunction(v) } diff --git a/edn/src/entities.rs b/edn/src/entities.rs index 17610e20..1ddb4552 100644 --- a/edn/src/entities.rs +++ b/edn/src/entities.rs @@ -13,6 +13,10 @@ use std::collections::BTreeMap; use std::fmt; +use value_rc::{ + ValueRc, +}; + use symbols::{ Keyword, PlainSymbol, @@ -93,7 +97,7 @@ pub enum ValuePlace { Entid(EntidOrIdent), // We never know at parse-time whether a string is really a tempid, but we will often know when // building entities programmatically. - TempId(TempId), + TempId(ValueRc), LookupRef(LookupRef), TxFunction(TxFunction), Vector(Vec>), @@ -104,7 +108,7 @@ pub enum ValuePlace { #[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] pub enum EntityPlace { Entid(EntidOrIdent), - TempId(TempId), + TempId(ValueRc), LookupRef(LookupRef), TxFunction(TxFunction), }