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:
parent
106d6fae11
commit
76507623ac
4 changed files with 17 additions and 18 deletions
|
@ -72,7 +72,7 @@ impl TransactableValue for ValueAndSpan {
|
||||||
bail!(DbErrorKind::InputError(errors::InputError::BadEntityPlace))
|
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) => {
|
List(ls) => {
|
||||||
let mut it = ls.iter();
|
let mut it = ls.iter();
|
||||||
match (it.next().map(|x| &x.inner), it.next(), it.next(), it.next()) {
|
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> {
|
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 {
|
match self {
|
||||||
TypedValue::Ref(x) => Ok(EntityPlace::Entid(entities::EntidOrIdent::Entid(x))),
|
TypedValue::Ref(x) => Ok(EntityPlace::Entid(entities::EntidOrIdent::Entid(x))),
|
||||||
TypedValue::Keyword(x) => Ok(EntityPlace::Entid(entities::EntidOrIdent::Ident((*x).clone()))),
|
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::Boolean(_) |
|
||||||
TypedValue::Long(_) |
|
TypedValue::Long(_) |
|
||||||
TypedValue::Double(_) |
|
TypedValue::Double(_) |
|
||||||
|
@ -134,7 +134,7 @@ impl TransactableValue for TypedValue {
|
||||||
|
|
||||||
fn as_tempid(&self) -> Option<TempId> {
|
fn as_tempid(&self) -> Option<TempId> {
|
||||||
match self {
|
match self {
|
||||||
&TypedValue::String(ref s) => Some(TempId::External((**s).clone())),
|
&TypedValue::String(ref s) => Some(TempId::External((**s).clone()).into()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
db/src/tx.rs
17
db/src/tx.rs
|
@ -65,7 +65,6 @@ use db::{
|
||||||
use edn::{
|
use edn::{
|
||||||
InternSet,
|
InternSet,
|
||||||
Keyword,
|
Keyword,
|
||||||
ValueRc,
|
|
||||||
};
|
};
|
||||||
use entids;
|
use entids;
|
||||||
use errors;
|
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)))
|
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
|
/// Allocate private internal tempids reserved for Mentat. Internal tempids just need to be
|
||||||
/// unique within one transaction; they should never escape a transaction.
|
/// unique within one transaction; they should never escape a transaction.
|
||||||
fn allocate_mentat_id<W: TransactableValue>(&mut self) -> entmod::EntityPlace<W> {
|
fn allocate_mentat_id<W: TransactableValue>(&mut self) -> entmod::EntityPlace<W> {
|
||||||
self.mentat_id_count += 1;
|
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>> {
|
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) => {
|
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) => {
|
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
|
// that the given value is in the attribute's value set, or (in
|
||||||
// limited cases) coerce the value into the attribute's value set.
|
// limited cases) coerce the value into the attribute's value set.
|
||||||
match v.as_tempid() {
|
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 => {
|
None => {
|
||||||
if let TypedValue::Ref(entid) = v.into_typed_value(&self.schema, ValueType::Ref)? {
|
if let TypedValue::Ref(entid) = v.into_typed_value(&self.schema, ValueType::Ref)? {
|
||||||
Ok(Either::Left(KnownEntid(entid)))
|
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)?))),
|
Ok(Either::Left(KnownEntid(self.entity_a_into_term_a(entid)?))),
|
||||||
|
|
||||||
entmod::ValuePlace::TempId(tempid) =>
|
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) =>
|
entmod::ValuePlace::LookupRef(ref lookup_ref) =>
|
||||||
Ok(Either::Right(LookupRefOrTempId::LookupRef(self.intern_lookup_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.
|
// limited cases) coerce the value into the attribute's value set.
|
||||||
if attribute.value_type == ValueType::Ref {
|
if attribute.value_type == ValueType::Ref {
|
||||||
match v.as_tempid() {
|
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)?,
|
None => v.into_typed_value(&self.schema, attribute.value_type).map(Either::Left)?,
|
||||||
}
|
}
|
||||||
} else {
|
} 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)?)),
|
Either::Left(TypedValue::Ref(in_process.entity_a_into_term_a(entid)?)),
|
||||||
|
|
||||||
entmod::ValuePlace::TempId(tempid) =>
|
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) => {
|
entmod::ValuePlace::LookupRef(ref lookup_ref) => {
|
||||||
if attribute.value_type != ValueType::Ref {
|
if attribute.value_type != ValueType::Ref {
|
||||||
|
|
|
@ -260,7 +260,7 @@ tx_function -> TxFunction
|
||||||
= "(" __ n:$(symbol_name) __ ")" { TxFunction { op: PlainSymbol::plain(n) } }
|
= "(" __ n:$(symbol_name) __ ")" { TxFunction { op: PlainSymbol::plain(n) } }
|
||||||
|
|
||||||
entity_place -> EntityPlace<ValueAndSpan>
|
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:entid { EntityPlace::Entid(v) }
|
||||||
/ v:lookup_ref { EntityPlace::LookupRef(v) }
|
/ v:lookup_ref { EntityPlace::LookupRef(v) }
|
||||||
/ v:tx_function { EntityPlace::TxFunction(v) }
|
/ v:tx_function { EntityPlace::TxFunction(v) }
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use value_rc::{
|
||||||
|
ValueRc,
|
||||||
|
};
|
||||||
|
|
||||||
use symbols::{
|
use symbols::{
|
||||||
Keyword,
|
Keyword,
|
||||||
PlainSymbol,
|
PlainSymbol,
|
||||||
|
@ -93,7 +97,7 @@ pub enum ValuePlace<V> {
|
||||||
Entid(EntidOrIdent),
|
Entid(EntidOrIdent),
|
||||||
// We never know at parse-time whether a string is really a tempid, but we will often know when
|
// We never know at parse-time whether a string is really a tempid, but we will often know when
|
||||||
// building entities programmatically.
|
// building entities programmatically.
|
||||||
TempId(TempId),
|
TempId(ValueRc<TempId>),
|
||||||
LookupRef(LookupRef<V>),
|
LookupRef(LookupRef<V>),
|
||||||
TxFunction(TxFunction),
|
TxFunction(TxFunction),
|
||||||
Vector(Vec<ValuePlace<V>>),
|
Vector(Vec<ValuePlace<V>>),
|
||||||
|
@ -104,7 +108,7 @@ pub enum ValuePlace<V> {
|
||||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
||||||
pub enum EntityPlace<V> {
|
pub enum EntityPlace<V> {
|
||||||
Entid(EntidOrIdent),
|
Entid(EntidOrIdent),
|
||||||
TempId(TempId),
|
TempId(ValueRc<TempId>),
|
||||||
LookupRef(LookupRef<V>),
|
LookupRef(LookupRef<V>),
|
||||||
TxFunction(TxFunction),
|
TxFunction(TxFunction),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue