Implement conversion from IceResult into BreadcrumbTreeNode.

I believe this change will remove an extra heap allocation I was doing in the new_breadcrumbs_* functions for the explicit context by adding support for converting from Rc<dyn ContextElement> to Rc<dyn IntoContextElement> without copying the underlying data. This should allow conversion of the IceResult::Owned variant to the BreadcrumbTreeElement::Owned variant without extra copying.
This commit is contained in:
Tom Alexander 2020-06-06 19:39:44 -04:00
parent 7253c7d99e
commit f9dea70d23
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 31 additions and 6 deletions

View File

@ -1,5 +1,7 @@
use crate::renderer::context_element::ContextElement;
use crate::renderer::context_element::IceResult; use crate::renderer::context_element::IceResult;
use crate::renderer::context_element::IntoContextElement; use crate::renderer::context_element::IntoContextElement;
use crate::renderer::context_element::IntoRcIce;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::rc::Rc; use std::rc::Rc;
@ -29,6 +31,15 @@ impl<'a> From<&'a IceResult<'a>> for BreadcrumbTreeElement<'a> {
} }
} }
impl<'a> From<IceResult<'a>> for BreadcrumbTreeElement<'a> {
fn from(inp: IceResult<'a>) -> Self {
match inp {
IceResult::Owned(rc_ce) => BreadcrumbTreeElement::Owned(rc_ce.into_rc_ice()),
IceResult::Borrowed(ce) => BreadcrumbTreeElement::Borrowed(ce.from_context_element()),
}
}
}
impl<'a> BreadcrumbTree<'a> { impl<'a> BreadcrumbTree<'a> {
pub fn new(parent: Option<&'a BreadcrumbTree>, element: BreadcrumbTreeElement<'a>) -> Self { pub fn new(parent: Option<&'a BreadcrumbTree>, element: BreadcrumbTreeElement<'a>) -> Self {
BreadcrumbTree { BreadcrumbTree {

View File

@ -16,6 +16,7 @@ pub trait ContextElement:
// + CloneIntoBoxedContextElement // + CloneIntoBoxedContextElement
+ CompareContextElement + CompareContextElement
+ FromContextElement + FromContextElement
+ IntoRcIce
{ {
} }
@ -119,6 +120,16 @@ impl<C: ContextElement> IntoContextElement for C {
} }
} }
pub trait IntoRcIce {
fn into_rc_ice(self: Rc<Self>) -> Rc<dyn IntoContextElement>;
}
impl<C: 'static + ContextElement> IntoRcIce for C {
fn into_rc_ice(self: Rc<C>) -> Rc<dyn IntoContextElement> {
Rc::clone(&self) as Rc<dyn IntoContextElement>
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum IceResult<'a> { pub enum IceResult<'a> {
// Using Rc so that when we need to create BreadcrumbTrees with // Using Rc so that when we need to create BreadcrumbTrees with

View File

@ -3,6 +3,7 @@ use crate::parser::KVPair;
use crate::parser::OwnedLiteral; use crate::parser::OwnedLiteral;
use crate::parser::RValue; use crate::parser::RValue;
use crate::renderer::breadcrumb_tree::BreadcrumbTree; use crate::renderer::breadcrumb_tree::BreadcrumbTree;
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
use crate::renderer::context_element::CompareContextElement; use crate::renderer::context_element::CompareContextElement;
use crate::renderer::context_element::ContextElement; use crate::renderer::context_element::ContextElement;
use crate::renderer::context_element::IceResult; use crate::renderer::context_element::IceResult;
@ -21,7 +22,7 @@ use std::rc::Rc;
#[derive(Debug)] #[derive(Debug)]
pub struct ParametersContext<'a> { pub struct ParametersContext<'a> {
params: HashMap<&'a str, &'a dyn IntoContextElement>, params: HashMap<&'a str, BreadcrumbTreeElement<'a>>,
} }
impl<'a> ParametersContext<'a> { impl<'a> ParametersContext<'a> {
@ -38,12 +39,14 @@ impl<'a> ParametersContext<'a> {
// then those are resolved at the time of access rather than // then those are resolved at the time of access rather than
// the time of assignment, so we leave them into their // the time of assignment, so we leave them into their
// original IntoContextElement state. // original IntoContextElement state.
let rendered_params = params let rendered_params: HashMap<&'a str, BreadcrumbTreeElement<'a>> = params
.iter() .iter()
.map(|kvpair| { .map(|kvpair| {
let k = kvpair.key; let k = kvpair.key;
let v: &dyn IntoContextElement = match &kvpair.value { let v: BreadcrumbTreeElement<'a> = match &kvpair.value {
RValue::RVLiteral(owned_literal) => &kvpair.value, RValue::RVLiteral(owned_literal) => {
BreadcrumbTreeElement::Borrowed(&kvpair.value)
}
/*RValue::RVPath(path) => kvpair /*RValue::RVPath(path) => kvpair
.value .value
.into_context_element(renderer, breadcrumbs) .into_context_element(renderer, breadcrumbs)

View File

@ -227,7 +227,7 @@ impl<'a> DustRenderer<'a> {
.flatten() .flatten()
.map(|val| { .map(|val| {
if val.get_context_element_reference().is_truthy() { if val.get_context_element_reference().is_truthy() {
new_nodes.push(BreadcrumbTreeElement::Owned(Rc::new(val))) new_nodes.push(std::convert::From::from(val))
} }
}); });
}); });
@ -297,7 +297,7 @@ impl<'a> DustRenderer<'a> {
.flatten() .flatten()
.map(|val| { .map(|val| {
if val.get_context_element_reference().is_truthy() { if val.get_context_element_reference().is_truthy() {
new_nodes.push(BreadcrumbTreeElement::Owned(Rc::new(val))); new_nodes.push(std::convert::From::from(val));
} }
}); });
}); });