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.
This commit is contained in:
Nick Alexander 2018-07-02 10:33:43 -07:00
parent 106d6fae11
commit 76507623ac
4 changed files with 17 additions and 18 deletions

View file

@ -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<TempId> {
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<TempId> {
match self {
&TypedValue::String(ref s) => Some(TempId::External((**s).clone())),
&TypedValue::String(ref s) => Some(TempId::External((**s).clone()).into()),
_ => None,
}
}

View file

@ -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<TempId> {
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<W: TransactableValue>(&mut self) -> entmod::EntityPlace<W> {
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<W: TransactableValue>(&mut self, x: entmod::EntityPlace<W>) -> Result<KnownEntidOr<LookupRefOrTempId>> {
@ -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 {

View file

@ -260,7 +260,7 @@ tx_function -> TxFunction
= "(" __ n:$(symbol_name) __ ")" { TxFunction { op: PlainSymbol::plain(n) } }
entity_place -> EntityPlace<ValueAndSpan>
= 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) }

View file

@ -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<V> {
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<TempId>),
LookupRef(LookupRef<V>),
TxFunction(TxFunction),
Vector(Vec<ValuePlace<V>>),
@ -104,7 +108,7 @@ pub enum ValuePlace<V> {
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
pub enum EntityPlace<V> {
Entid(EntidOrIdent),
TempId(TempId),
TempId(ValueRc<TempId>),
LookupRef(LookupRef<V>),
TxFunction(TxFunction),
}