Skip to content

Commit d8a455a

Browse files
authored
Merge pull request #191 from epage/arc
perf: Reduce allocations
2 parents 84c6f23 + cbb1d25 commit d8a455a

File tree

5 files changed

+34
-24
lines changed

5 files changed

+34
-24
lines changed

src/interpreter/context.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::collections::HashMap;
2+
use std::sync;
23

34
use error::{Error, Result};
45
use value::{Index, Object, Value};
@@ -39,7 +40,7 @@ pub struct Context {
3940
cycles: HashMap<String, usize>,
4041

4142
// Public for backwards compatability
42-
filters: HashMap<&'static str, BoxedValueFilter>,
43+
filters: sync::Arc<HashMap<&'static str, BoxedValueFilter>>,
4344
}
4445

4546
impl Context {
@@ -53,8 +54,8 @@ impl Context {
5354
self
5455
}
5556

56-
pub fn with_filters(mut self, filters: HashMap<&'static str, BoxedValueFilter>) -> Self {
57-
self.filters = filters;
57+
pub fn with_filters(mut self, filters: &sync::Arc<HashMap<&'static str, BoxedValueFilter>>) -> Self {
58+
self.filters = sync::Arc::clone(filters);
5859
self
5960
}
6061

@@ -76,10 +77,6 @@ impl Context {
7677
Ok(Some(val))
7778
}
7879

79-
pub fn add_filter(&mut self, name: &'static str, filter: BoxedValueFilter) {
80-
self.filters.insert(name, filter);
81-
}
82-
8380
pub fn get_filter<'b>(&'b self, name: &str) -> Option<&'b FilterValue> {
8481
self.filters.get(name).map(|f| {
8582
let f: &FilterValue = f;

src/parser.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::HashMap;
22
use std::fs::File;
33
use std::io::prelude::Read;
44
use std::path;
5+
use std::sync;
56

67
use super::Template;
78
use compiler;
@@ -203,14 +204,15 @@ impl ParserBuilder {
203204
tags,
204205
include_source,
205206
};
207+
let filters = sync::Arc::new(filters);
206208
Parser { options, filters }
207209
}
208210
}
209211

210212
#[derive(Default, Clone)]
211213
pub struct Parser {
212214
options: compiler::LiquidOptions,
213-
filters: HashMap<&'static str, interpreter::BoxedValueFilter>,
215+
filters: sync::Arc<HashMap<&'static str, interpreter::BoxedValueFilter>>,
214216
}
215217

216218
impl Parser {
@@ -236,7 +238,7 @@ impl Parser {
236238
pub fn parse(&self, text: &str) -> Result<Template> {
237239
let tokens = compiler::tokenize(text)?;
238240
let template = compiler::parse(&tokens, &self.options).map(interpreter::Template::new)?;
239-
let filters = self.filters.clone();
241+
let filters = sync::Arc::clone(&self.filters);
240242
Ok(Template { template, filters })
241243
}
242244

src/tags/for_block.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,14 @@ pub fn for_block(
300300

301301
#[cfg(test)]
302302
mod test {
303-
use super::*;
303+
use std::collections::HashMap;
304+
use std::sync;
305+
304306
use compiler;
305307
use interpreter;
306308

309+
use super::*;
310+
307311
fn options() -> LiquidOptions {
308312
let mut options = LiquidOptions::default();
309313
options
@@ -634,13 +638,13 @@ mod test {
634638
&options(),
635639
).unwrap();
636640

637-
let mut data: Context = Default::default();
638-
data.add_filter(
639-
"shout",
641+
let mut filters: HashMap<&'static str, interpreter::BoxedValueFilter> = HashMap::new();
642+
filters.insert("shout",
640643
((|input, _args| Ok(Value::scalar(input.to_str().to_uppercase())))
641644
as interpreter::FnFilterValue)
642645
.into(),
643-
);
646+
);
647+
let mut data = Context::new().with_filters(&sync::Arc::new(filters));
644648

645649
data.set_global_val(
646650
"array",

src/tags/include_tag.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,18 @@ pub fn include_tag(
5353

5454
#[cfg(test)]
5555
mod test {
56-
use super::*;
57-
use compiler;
58-
use filters;
59-
use interpreter;
6056
use std::iter::FromIterator;
6157
use std::path;
58+
use std::collections::HashMap;
59+
use std::sync;
60+
6261
use tags;
6362
use value;
63+
use compiler;
64+
use filters;
65+
use interpreter;
66+
67+
use super::*;
6468

6569
fn options() -> LiquidOptions {
6670
let include_path = path::PathBuf::from_iter("tests/fixtures/input".split('/'));
@@ -88,10 +92,11 @@ mod test {
8892
.map(interpreter::Template::new)
8993
.unwrap();
9094

91-
let mut context = Context::new();
95+
let mut filters: HashMap<&'static str, interpreter::BoxedValueFilter> = HashMap::new();
96+
filters.insert("size",(filters::size as interpreter::FnFilterValue).into());
97+
let mut context = Context::new().with_filters(&sync::Arc::new(filters));
9298
context.set_global_val("num", value::Value::scalar(5f64));
9399
context.set_global_val("numTwo", value::Value::scalar(10f64));
94-
context.add_filter("size", (filters::size as interpreter::FnFilterValue).into());
95100
let output = template.render(&mut context).unwrap();
96101
assert_eq!(output, Some("5 wat wot\n".to_owned()));
97102
}
@@ -104,10 +109,11 @@ mod test {
104109
.map(interpreter::Template::new)
105110
.unwrap();
106111

107-
let mut context = Context::new();
112+
let mut filters: HashMap<&'static str, interpreter::BoxedValueFilter> = HashMap::new();
113+
filters.insert("size",(filters::size as interpreter::FnFilterValue).into());
114+
let mut context = Context::new().with_filters(&sync::Arc::new(filters));
108115
context.set_global_val("num", value::Value::scalar(5f64));
109116
context.set_global_val("numTwo", value::Value::scalar(10f64));
110-
context.add_filter("size", (filters::size as interpreter::FnFilterValue).into());
111117
let output = template.render(&mut context).unwrap();
112118
assert_eq!(output, Some("5 wat wot\n".to_owned()));
113119
}

src/template.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::collections::HashMap;
2+
use std::sync;
23

34
use super::Object;
45
use error::Result;
@@ -8,14 +9,14 @@ use interpreter::Renderable;
89

910
pub struct Template {
1011
pub(crate) template: interpreter::Template,
11-
pub(crate) filters: HashMap<&'static str, interpreter::BoxedValueFilter>,
12+
pub(crate) filters: sync::Arc<HashMap<&'static str, interpreter::BoxedValueFilter>>,
1213
}
1314

1415
impl Template {
1516
/// Renders an instance of the Template, using the given globals.
1617
pub fn render(&self, globals: &Object) -> Result<String> {
1718
let mut data = interpreter::Context::new()
18-
.with_filters(self.filters.clone())
19+
.with_filters(&self.filters)
1920
.with_values(globals.clone());
2021
let output = self.template
2122
.render(&mut data)?

0 commit comments

Comments
 (0)