Part 2: Use ValueRc in InternSet.

We haven't observed performance issues using `Arc` instead of `Rc`,
and we want to be able to include things that are interned (including,
soon, `TempId` instances) in errors coming out of the
transactor.  (And `Rc` isn't `Sync`, so it can't be included in errors
directly.)
This commit is contained in:
Nick Alexander 2018-07-02 09:34:57 -07:00
parent 87f850a44e
commit 02a163a10f
3 changed files with 21 additions and 21 deletions

View file

@ -17,7 +17,6 @@ use std::collections::{
BTreeSet,
HashMap,
};
use std::rc::Rc;
use mentat_core::KnownEntid;
@ -27,6 +26,14 @@ use edn;
use edn::{
SpannedValue,
ValueAndSpan,
ValueRc,
};
use edn::entities;
use edn::entities::{
EntityPlace,
OpType,
TempId,
TxFunction,
};
use errors;
@ -47,13 +54,6 @@ use types::{
TypedValue,
ValueType,
};
use edn::entities;
use edn::entities::{
EntityPlace,
OpType,
TempId,
TxFunction,
};
impl TransactableValue for ValueAndSpan {
fn into_typed_value(self, schema: &Schema, value_type: ValueType) -> Result<TypedValue> {
@ -150,10 +150,10 @@ use self::Either::*;
pub type KnownEntidOr<T> = Either<KnownEntid, T>;
pub type TypedValueOr<T> = Either<TypedValue, T>;
pub type TempIdHandle = Rc<TempId>;
pub type TempIdHandle = ValueRc<TempId>;
pub type TempIdMap = HashMap<TempIdHandle, KnownEntid>;
pub type LookupRef = Rc<AVPair>;
pub type LookupRef = ValueRc<AVPair>;
/// Internal representation of an entid on its way to resolution. We either have the simple case (a
/// numeric entid), a lookup-ref that still needs to be resolved (an atomized [a v] pair), or a temp

View file

@ -56,9 +56,6 @@ use std::collections::{
use std::iter::{
once,
};
use std::rc::{
Rc,
};
use db;
use db::{
@ -68,6 +65,7 @@ use db::{
use edn::{
InternSet,
Keyword,
ValueRc,
};
use entids;
use errors;
@ -303,7 +301,7 @@ 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) -> Rc<TempId> {
fn intern_temp_id(&mut self, temp_id: TempId) -> ValueRc<TempId> {
self.temp_ids.intern(temp_id)
}

View file

@ -12,7 +12,10 @@
use std::collections::HashSet;
use std::hash::Hash;
use std::rc::Rc;
use ::{
ValueRc,
};
/// An `InternSet` allows to "intern" some potentially large values, maintaining a single value
/// instance owned by the `InternSet` and leaving consumers with lightweight ref-counted handles to
@ -23,7 +26,7 @@ use std::rc::Rc;
/// See https://en.wikipedia.org/wiki/String_interning for discussion.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct InternSet<T> where T: Eq + Hash {
pub inner: HashSet<Rc<T>>,
pub inner: HashSet<ValueRc<T>>,
}
impl<T> InternSet<T> where T: Eq + Hash {
@ -40,13 +43,12 @@ impl<T> InternSet<T> where T: Eq + Hash {
/// Intern a value, providing a ref-counted handle to the interned value.
///
/// ```
/// use std::rc::Rc;
/// use edn::intern_set::InternSet;
/// use edn::{InternSet, ValueRc};
///
/// let mut s = InternSet::new();
///
/// let one = "foo".to_string();
/// let two = Rc::new("foo".to_string());
/// let two = ValueRc::new("foo".to_string());
///
/// let out_one = s.intern(one);
/// assert_eq!(out_one, two);
@ -57,8 +59,8 @@ impl<T> InternSet<T> where T: Eq + Hash {
/// assert_eq!(1, s.inner.len());
/// // assert!(&out_one.ptr_eq(&out_two)); // Nightly-only.
/// ```
pub fn intern<R: Into<Rc<T>>>(&mut self, value: R) -> Rc<T> {
let key: Rc<T> = value.into();
pub fn intern<R: Into<ValueRc<T>>>(&mut self, value: R) -> ValueRc<T> {
let key: ValueRc<T> = value.into();
if self.inner.insert(key.clone()) {
key
} else {