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:
parent
87f850a44e
commit
02a163a10f
3 changed files with 21 additions and 21 deletions
|
@ -17,7 +17,6 @@ use std::collections::{
|
||||||
BTreeSet,
|
BTreeSet,
|
||||||
HashMap,
|
HashMap,
|
||||||
};
|
};
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use mentat_core::KnownEntid;
|
use mentat_core::KnownEntid;
|
||||||
|
|
||||||
|
@ -27,6 +26,14 @@ use edn;
|
||||||
use edn::{
|
use edn::{
|
||||||
SpannedValue,
|
SpannedValue,
|
||||||
ValueAndSpan,
|
ValueAndSpan,
|
||||||
|
ValueRc,
|
||||||
|
};
|
||||||
|
use edn::entities;
|
||||||
|
use edn::entities::{
|
||||||
|
EntityPlace,
|
||||||
|
OpType,
|
||||||
|
TempId,
|
||||||
|
TxFunction,
|
||||||
};
|
};
|
||||||
|
|
||||||
use errors;
|
use errors;
|
||||||
|
@ -47,13 +54,6 @@ use types::{
|
||||||
TypedValue,
|
TypedValue,
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
use edn::entities;
|
|
||||||
use edn::entities::{
|
|
||||||
EntityPlace,
|
|
||||||
OpType,
|
|
||||||
TempId,
|
|
||||||
TxFunction,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl TransactableValue for ValueAndSpan {
|
impl TransactableValue for ValueAndSpan {
|
||||||
fn into_typed_value(self, schema: &Schema, value_type: ValueType) -> Result<TypedValue> {
|
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 KnownEntidOr<T> = Either<KnownEntid, T>;
|
||||||
pub type TypedValueOr<T> = Either<TypedValue, 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 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
|
/// 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
|
/// numeric entid), a lookup-ref that still needs to be resolved (an atomized [a v] pair), or a temp
|
||||||
|
|
|
@ -56,9 +56,6 @@ use std::collections::{
|
||||||
use std::iter::{
|
use std::iter::{
|
||||||
once,
|
once,
|
||||||
};
|
};
|
||||||
use std::rc::{
|
|
||||||
Rc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use db;
|
use db;
|
||||||
use db::{
|
use db::{
|
||||||
|
@ -68,6 +65,7 @@ use db::{
|
||||||
use edn::{
|
use edn::{
|
||||||
InternSet,
|
InternSet,
|
||||||
Keyword,
|
Keyword,
|
||||||
|
ValueRc,
|
||||||
};
|
};
|
||||||
use entids;
|
use entids;
|
||||||
use errors;
|
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)))
|
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)
|
self.temp_ids.intern(temp_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::rc::Rc;
|
|
||||||
|
use ::{
|
||||||
|
ValueRc,
|
||||||
|
};
|
||||||
|
|
||||||
/// An `InternSet` allows to "intern" some potentially large values, maintaining a single value
|
/// 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
|
/// 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.
|
/// See https://en.wikipedia.org/wiki/String_interning for discussion.
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
pub struct InternSet<T> where T: Eq + Hash {
|
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 {
|
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.
|
/// Intern a value, providing a ref-counted handle to the interned value.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::rc::Rc;
|
/// use edn::{InternSet, ValueRc};
|
||||||
/// use edn::intern_set::InternSet;
|
|
||||||
///
|
///
|
||||||
/// let mut s = InternSet::new();
|
/// let mut s = InternSet::new();
|
||||||
///
|
///
|
||||||
/// let one = "foo".to_string();
|
/// 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);
|
/// let out_one = s.intern(one);
|
||||||
/// assert_eq!(out_one, two);
|
/// assert_eq!(out_one, two);
|
||||||
|
@ -57,8 +59,8 @@ impl<T> InternSet<T> where T: Eq + Hash {
|
||||||
/// assert_eq!(1, s.inner.len());
|
/// assert_eq!(1, s.inner.len());
|
||||||
/// // assert!(&out_one.ptr_eq(&out_two)); // Nightly-only.
|
/// // assert!(&out_one.ptr_eq(&out_two)); // Nightly-only.
|
||||||
/// ```
|
/// ```
|
||||||
pub fn intern<R: Into<Rc<T>>>(&mut self, value: R) -> Rc<T> {
|
pub fn intern<R: Into<ValueRc<T>>>(&mut self, value: R) -> ValueRc<T> {
|
||||||
let key: Rc<T> = value.into();
|
let key: ValueRc<T> = value.into();
|
||||||
if self.inner.insert(key.clone()) {
|
if self.inner.insert(key.clone()) {
|
||||||
key
|
key
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue