Slim down the common case of no annotations

This commit is contained in:
Tony Garnock-Jones 2020-06-17 02:39:01 +02:00
parent 078e8dd4e8
commit f2910eb8d0
4 changed files with 94 additions and 54 deletions

View File

@ -253,8 +253,8 @@ mod decoder_tests {
let mut buf = &b"\x0521"[..];
let mut d = decoder::from_bytes(&mut buf);
let v = d.demand_next().unwrap();
assert_eq!(v.annotations().len(), 1);
assert_eq!(v.annotations()[0], Value::from(2).wrap());
assert_eq!(v.annotations().slice().len(), 1);
assert_eq!(v.annotations().slice()[0], Value::from(2).wrap());
assert_eq!(v.value(), &Value::from(1));
}
@ -263,7 +263,7 @@ mod decoder_tests {
let mut d = decoder::from_bytes(&mut buf);
d.set_read_annotations(false);
let v = d.demand_next().unwrap();
assert_eq!(v.annotations().len(), 0);
assert_eq!(v.annotations().slice().len(), 0);
assert_eq!(v.value(), &Value::from(1));
}

View File

@ -20,9 +20,12 @@ impl<'a, W: Writer> Encoder<'a, W> {
}
pub fn write(&mut self, v: &IOValue) -> Result {
for ann in v.annotations() {
self.write.write_annotation_prefix()?;
self.write(ann)?;
match v.annotations().maybe_slice() {
None => (),
Some(anns) => for ann in anns {
self.write.write_annotation_prefix()?;
self.write(ann)?;
}
}
self.write_value(v.value())
}

View File

@ -7,7 +7,7 @@ use std::io::{Read, Error};
use std::marker::PhantomData;
use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor};
use super::signed_integer::SignedInteger;
use super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record};
use super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations};
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_eof, io_syntax_error};
pub type IOResult<T> = std::result::Result<T, Error>;
@ -592,8 +592,8 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
annotations.push(self.demand_next(read_annotations)?.into_owned());
}
let (existing_annotations, v) = self.demand_next(read_annotations)?.into_owned().pieces();
annotations.extend(existing_annotations);
Cow::Owned(IOValue::wrap_ann(annotations, v))
annotations.extend_from_slice(existing_annotations.slice());
Cow::Owned(IOValue::wrap(Annotations::new(Some(annotations)), v))
} else {
self.skip_value()?;
continue;

View File

@ -6,6 +6,7 @@ use std::convert::TryFrom;
use std::convert::TryInto;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::ops::Index;
use std::ops::IndexMut;
use std::string::String;
@ -26,16 +27,15 @@ pub trait Domain: Sized + Debug + Clone + Eq + Hash + Ord {
}
pub trait NestedValue<D: Domain>: Sized + Debug + Clone + Eq + Hash + Ord {
fn wrap(v: Value<Self, D>) -> Self;
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self;
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self;
fn annotations(&self) -> &[Self];
fn annotations(&self) -> &Annotations<Self, D>;
fn value(&self) -> &Value<Self, D>;
fn pieces(self) -> (Vec<Self>, Value<Self, D>);
fn pieces(self) -> (Annotations<Self, D>, Value<Self, D>);
fn value_owned(self) -> Value<Self, D>;
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for ann in self.annotations() {
for ann in self.annotations().slice() {
write!(f, "@{:?} ", ann)?;
}
self.value().fmt(f)
@ -45,8 +45,7 @@ pub trait NestedValue<D: Domain>: Sized + Debug + Clone + Eq + Hash + Ord {
where
F: Fn(&D) -> Value<M, E>
{
M::wrap_ann(self.annotations().iter().map(|a| a.copy_via(f)).collect(),
self.value().copy_via(f))
M::wrap(self.annotations().copy_via(f), self.value().copy_via(f))
}
fn to_io_value(&self) -> IOValue {
@ -280,7 +279,7 @@ impl<N: NestedValue<D>, D: Domain> Debug for Value<N, D> {
impl<N: NestedValue<D>, D: Domain> Value<N, D> {
pub fn wrap(self) -> N {
N::wrap(self)
N::wrap(Annotations::empty(), self)
}
fn expected(&self, k: ExpectedKind) -> Error {
@ -802,10 +801,64 @@ pub fn deserialize_nested_value<'de, D, N, Dom: Domain>(deserializer: D) ->
//---------------------------------------------------------------------------
#[derive(Clone)]
pub struct Annotations<N: NestedValue<D>, D: Domain>(Option<Box<Vec<N>>>, PhantomData<D>);
impl<N: NestedValue<D>, D: Domain> Annotations<N, D> {
pub fn empty() -> Self {
Annotations(None,
PhantomData)
}
pub fn new(anns: Option<Vec<N>>) -> Self {
Annotations(anns.and_then(|v| if v.is_empty() { None } else { Some(Box::new(v)) }),
PhantomData)
}
pub fn maybe_slice(&self) -> Option<&[N]> {
match self.0 {
None => None,
Some(ref b) => Some(&&b[..]),
}
}
pub fn slice(&self) -> &[N] {
self.maybe_slice().unwrap_or(&[])
}
pub fn modify<F>(&mut self, f: F) -> &mut Self
where
F: FnOnce(&mut Vec<N>)
{
let mut v: Vec<N> = self.0.take().map_or_else(|| vec![], |b| *b);
f(&mut v);
self.0 = if v.is_empty() { None } else { Some(Box::new(v)) };
self
}
pub fn copy_via<M: NestedValue<E>, E: Domain, F>(&self, f: &F) -> Annotations<M, E>
where
F: Fn(&D) -> Value<M, E>
{
match self.0 {
None =>
Annotations(None, PhantomData),
Some(ref b) =>
Annotations(Some(Box::new(b.iter().map(|a| a.copy_via(f)).collect())), PhantomData),
}
}
}
/// An possibly-annotated Value, with annotations (themselves
/// possibly-annotated) in order of appearance.
#[derive(Clone)]
pub struct AnnotatedValue<N: NestedValue<D>, D: Domain>(pub Vec<N>, pub Value<N, D>);
pub struct AnnotatedValue<N: NestedValue<D>, D: Domain>(pub Annotations<N, D>, pub Value<N, D>);
impl<N: NestedValue<D>, D: Domain> AnnotatedValue<N, D> {
fn new(anns: Annotations<N, D>, value: Value<N, D>) -> Self {
AnnotatedValue(anns, value)
}
}
impl<N: NestedValue<D>, D: Domain> PartialEq for AnnotatedValue<N, D> {
fn eq(&self, other: &Self) -> bool {
@ -839,7 +892,7 @@ impl<N: NestedValue<D>, D: Domain> Ord for AnnotatedValue<N, D> {
pub struct PlainValue<D: Domain>(AnnotatedValue<PlainValue<D>, D>);
impl<D: Domain> PlainValue<D> {
pub fn annotations_mut(&mut self) -> &mut Vec<Self> {
pub fn annotations_mut(&mut self) -> &mut Annotations<Self, D> {
&mut (self.0).0
}
@ -849,15 +902,11 @@ impl<D: Domain> PlainValue<D> {
}
impl<D: Domain> NestedValue<D> for PlainValue<D> {
fn wrap(v: Value<Self, D>) -> Self {
Self::wrap_ann(Vec::new(), v)
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
PlainValue(AnnotatedValue::new(anns, v))
}
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
PlainValue(AnnotatedValue(anns, v))
}
fn annotations(&self) -> &[Self] {
fn annotations(&self) -> &Annotations<Self, D> {
&(self.0).0
}
@ -865,7 +914,7 @@ impl<D: Domain> NestedValue<D> for PlainValue<D> {
&(self.0).1
}
fn pieces(self) -> (Vec<Self>, Value<Self, D>) {
fn pieces(self) -> (Annotations<Self, D>, Value<Self, D>) {
let AnnotatedValue(anns, v) = self.0;
(anns, v)
}
@ -901,15 +950,11 @@ use std::rc::Rc;
pub struct RcValue<D: Domain>(Rc<AnnotatedValue<RcValue<D>, D>>);
impl<D: Domain> NestedValue<D> for RcValue<D> {
fn wrap(v: Value<Self, D>) -> Self {
Self::wrap_ann(Vec::new(), v)
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
RcValue(Rc::new(AnnotatedValue::new(anns, v)))
}
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
RcValue(Rc::new(AnnotatedValue(anns, v)))
}
fn annotations(&self) -> &[Self] {
fn annotations(&self) -> &Annotations<Self, D> {
&(self.0).0
}
@ -917,7 +962,7 @@ impl<D: Domain> NestedValue<D> for RcValue<D> {
&(self.0).1
}
fn pieces(self) -> (Vec<Self>, Value<Self, D>) {
fn pieces(self) -> (Annotations<Self, D>, Value<Self, D>) {
match Rc::try_unwrap(self.0) {
Ok(AnnotatedValue(anns, v)) => (anns, v),
Err(r) => (r.0.clone(), r.1.clone()),
@ -955,15 +1000,11 @@ use std::sync::Arc;
pub struct ArcValue<D: Domain>(Arc<AnnotatedValue<ArcValue<D>, D>>);
impl<D: Domain> NestedValue<D> for ArcValue<D> {
fn wrap(v: Value<Self, D>) -> Self {
Self::wrap_ann(Vec::new(), v)
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
ArcValue(Arc::new(AnnotatedValue::new(anns, v)))
}
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
ArcValue(Arc::new(AnnotatedValue(anns, v)))
}
fn annotations(&self) -> &[Self] {
fn annotations(&self) -> &Annotations<Self, D> {
&(self.0).0
}
@ -971,7 +1012,7 @@ impl<D: Domain> NestedValue<D> for ArcValue<D> {
&(self.0).1
}
fn pieces(self) -> (Vec<Self>, Value<Self, D>) {
fn pieces(self) -> (Annotations<Self, D>, Value<Self, D>) {
match Arc::try_unwrap(self.0) {
Ok(AnnotatedValue(anns, v)) => (anns, v),
Err(r) => (r.0.clone(), r.1.clone()),
@ -1012,21 +1053,17 @@ pub struct IOValue(Arc<AnnotatedValue<IOValue, NullDomain>>);
pub type UnwrappedIOValue = Value<IOValue, NullDomain>;
lazy_static! {
pub static ref FALSE: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Boolean(false))));
pub static ref TRUE: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Boolean(true))));
pub static ref EMPTY_SEQ: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Sequence(Vec::new()))));
pub static ref FALSE: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Boolean(false))));
pub static ref TRUE: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Boolean(true))));
pub static ref EMPTY_SEQ: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Sequence(Vec::new()))));
}
impl NestedValue<NullDomain> for IOValue {
fn wrap(v: Value<Self, NullDomain>) -> Self {
Self::wrap_ann(Vec::new(), v)
fn wrap(anns: Annotations<Self, NullDomain>, v: Value<Self, NullDomain>) -> Self {
IOValue(Arc::new(AnnotatedValue::new(anns, v)))
}
fn wrap_ann(anns: Vec<Self>, v: Value<Self, NullDomain>) -> Self {
IOValue(Arc::new(AnnotatedValue(anns, v)))
}
fn annotations(&self) -> &[Self] {
fn annotations(&self) -> &Annotations<Self, NullDomain> {
&(self.0).0
}
@ -1034,7 +1071,7 @@ impl NestedValue<NullDomain> for IOValue {
&(self.0).1
}
fn pieces(self) -> (Vec<Self>, Value<Self, NullDomain>) {
fn pieces(self) -> (Annotations<Self, NullDomain>, Value<Self, NullDomain>) {
match Arc::try_unwrap(self.0) {
Ok(AnnotatedValue(anns, v)) => (anns, v),
Err(r) => (r.0.clone(), r.1.clone()),