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,
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue