Skip to content

Commit 13903d7

Browse files
committed
Don't clone selection sets during execution
1 parent 6a4b883 commit 13903d7

File tree

9 files changed

+41
-46
lines changed

9 files changed

+41
-46
lines changed

src/executor.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub enum FieldPath<'a> {
3737
pub struct Executor<'a, CtxT> where CtxT: 'a {
3838
fragments: &'a HashMap<&'a str, &'a Fragment>,
3939
variables: &'a HashMap<String, InputValue>,
40-
current_selection_set: Option<Vec<Selection>>,
40+
current_selection_set: Option<&'a [Selection]>,
4141
schema: &'a SchemaType,
4242
context: &'a CtxT,
4343
errors: &'a RwLock<Vec<ExecutionError>>,
@@ -151,12 +151,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
151151

152152
/// Resolve a single arbitrary value into an `ExecutionResult`
153153
pub fn resolve<T: GraphQLType<Context=CtxT>>(&self, value: &T) -> ExecutionResult {
154-
Ok(value.resolve(
155-
match self.current_selection_set {
156-
Some(ref sel) => Some(sel.clone()),
157-
None => None,
158-
},
159-
self))
154+
Ok(value.resolve(self.current_selection_set, self))
160155
}
161156

162157
/// Resolve a single arbitrary value into a return value
@@ -194,7 +189,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
194189
&self,
195190
field_name: Option<String>,
196191
location: SourcePosition,
197-
selection_set: Option<Vec<Selection>>,
192+
selection_set: Option<&'a [Selection]>,
198193
)
199194
-> Executor<CtxT>
200195
{
@@ -339,7 +334,7 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
339334
let executor = Executor {
340335
fragments: &fragments.iter().map(|f| (f.item.name.item.as_str(), &f.item)).collect(),
341336
variables: variables,
342-
current_selection_set: Some(op.item.selection_set),
337+
current_selection_set: Some(&op.item.selection_set[..]),
343338
schema: &root_node.schema,
344339
context: context,
345340
errors: &errors,

src/macros/enums.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ macro_rules! graphql_enum {
8383
.into_meta()
8484
}
8585

86-
fn resolve(&self, _: Option<Vec<$crate::Selection>>, _: &$crate::Executor<Self::Context>) -> $crate::Value {
86+
fn resolve(&self, _: Option<&[$crate::Selection]>, _: &$crate::Executor<Self::Context>) -> $crate::Value {
8787
match self {
8888
$(
8989
&graphql_enum!(@as_pattern, $eval) =>

src/macros/interface.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ macro_rules! graphql_interface {
268268
fn resolve_into_type(
269269
&$mainself,
270270
type_name: &str,
271-
_: Option<Vec<$crate::Selection>>,
271+
_: Option<&[$crate::Selection]>,
272272
executor: &$crate::Executor<Self::Context>,
273273
)
274274
-> $crate::ExecutionResult

src/macros/scalar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ macro_rules! graphql_scalar {
7777

7878
fn resolve(
7979
&$resolve_selfvar,
80-
_: Option<Vec<$crate::Selection>>,
80+
_: Option<&[$crate::Selection]>,
8181
_: &$crate::Executor<Self::Context>) -> $crate::Value {
8282
$resolve_body
8383
}

src/macros/union.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ macro_rules! graphql_union {
137137
fn resolve_into_type(
138138
&$mainself,
139139
type_name: &str,
140-
_: Option<Vec<$crate::Selection>>,
140+
_: Option<&[$crate::Selection]>,
141141
executor: &$crate::Executor<Self::Context>,
142142
)
143143
-> $crate::ExecutionResult

src/types/base.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ pub trait GraphQLType: Sized {
248248
///
249249
/// The default implementation panics.
250250
#[allow(unused_variables)]
251-
fn resolve_into_type(&self, type_name: &str, selection_set: Option<Vec<Selection>>, executor: &Executor<Self::Context>) -> ExecutionResult {
251+
fn resolve_into_type(&self, type_name: &str, selection_set: Option<&[Selection]>, executor: &Executor<Self::Context>) -> ExecutionResult {
252252
if Self::name().unwrap() == type_name {
253253
Ok(self.resolve(selection_set, executor))
254254
} else {
@@ -274,7 +274,7 @@ pub trait GraphQLType: Sized {
274274
/// The default implementation uses `resolve_field` to resolve all fields,
275275
/// including those through fragment expansion, for object types. For
276276
/// non-object types, this method panics.
277-
fn resolve(&self, selection_set: Option<Vec<Selection>>, executor: &Executor<Self::Context>) -> Value {
277+
fn resolve(&self, selection_set: Option<&[Selection]>, executor: &Executor<Self::Context>) -> Value {
278278
if let Some(selection_set) = selection_set {
279279
let mut result = HashMap::new();
280280
resolve_selection_set_into(self, selection_set, executor, &mut result);
@@ -288,7 +288,7 @@ pub trait GraphQLType: Sized {
288288

289289
fn resolve_selection_set_into<T, CtxT>(
290290
instance: &T,
291-
selection_set: Vec<Selection>,
291+
selection_set: &[Selection],
292292
executor: &Executor<CtxT>,
293293
result: &mut HashMap<String, Value>)
294294
where T: GraphQLType<Context=CtxT>
@@ -299,11 +299,11 @@ fn resolve_selection_set_into<T, CtxT>(
299299

300300
for selection in selection_set {
301301
match selection {
302-
Selection::Field(Spanning { item: f, start: start_pos, .. }) => {
302+
&Selection::Field(Spanning { item: ref f, start: ref start_pos, .. }) => {
303303
if is_excluded(
304-
&match f.directives {
305-
Some(sel) => Some(sel.iter().cloned().map(|s| s.item).collect()),
306-
None => None,
304+
&match &f.directives {
305+
&Some(ref sel) => Some(sel.iter().cloned().map(|s| s.item).collect()),
306+
&None => None,
307307
},
308308
executor.variables()) {
309309
continue;
@@ -327,30 +327,30 @@ fn resolve_selection_set_into<T, CtxT>(
327327
let mut sub_exec = executor.sub_executor(
328328
Some(response_name.clone()),
329329
start_pos.clone(),
330-
f.selection_set);
330+
f.selection_set.as_ref().map(|v| &v[..]));
331331

332332
let field_result = instance.resolve_field(
333333
&f.name.item,
334334
&Arguments::new(
335-
f.arguments.map(|m|
336-
m.item.into_iter().map(|(k, v)|
335+
f.arguments.as_ref().map(|m|
336+
m.item.iter().cloned().map(|(k, v)|
337337
(k.item, v.item.into_const(exec_vars))).collect()),
338338
&meta_field.arguments),
339339
&mut sub_exec);
340340

341341
match field_result {
342342
Ok(v) => merge_key_into(result, response_name.clone(), v),
343343
Err(e) => {
344-
sub_exec.push_error(e, start_pos);
344+
sub_exec.push_error(e, start_pos.clone());
345345
result.insert(response_name.clone(), Value::null());
346346
}
347347
}
348348
},
349-
Selection::FragmentSpread(Spanning { item: spread, .. }) => {
349+
&Selection::FragmentSpread(Spanning { item: ref spread, .. }) => {
350350
if is_excluded(
351-
&match spread.directives {
352-
Some(sel) => Some(sel.iter().cloned().map(|s| s.item).collect()),
353-
None => None,
351+
&match &spread.directives {
352+
&Some(ref sel) => Some(sel.iter().cloned().map(|s| s.item).collect()),
353+
&None => None,
354354
},
355355
executor.variables()) {
356356
continue;
@@ -360,13 +360,13 @@ fn resolve_selection_set_into<T, CtxT>(
360360
.expect("Fragment could not be found");
361361

362362
resolve_selection_set_into(
363-
instance, fragment.selection_set.clone(), executor, result);
363+
instance, &fragment.selection_set[..], executor, result);
364364
},
365-
Selection::InlineFragment(Spanning { item: fragment, start: start_pos, .. }) => {
365+
&Selection::InlineFragment(Spanning { item: ref fragment, start: ref start_pos, .. }) => {
366366
if is_excluded(
367-
&match fragment.directives {
368-
Some(sel) => Some(sel.iter().cloned().map(|s| s.item).collect()),
369-
None => None
367+
&match &fragment.directives {
368+
&Some(ref sel) => Some(sel.iter().cloned().map(|s| s.item).collect()),
369+
&None => None
370370
},
371371
executor.variables()) {
372372
continue;
@@ -375,12 +375,12 @@ fn resolve_selection_set_into<T, CtxT>(
375375
let mut sub_exec = executor.sub_executor(
376376
None,
377377
start_pos.clone(),
378-
Some(fragment.selection_set.clone()));
378+
Some(&fragment.selection_set[..]));
379379

380-
if let Some(type_condition) = fragment.type_condition {
380+
if let &Some(ref type_condition) = &fragment.type_condition {
381381
let sub_result = instance.resolve_into_type(
382382
&type_condition.item,
383-
Some(fragment.selection_set.clone()),
383+
Some(&fragment.selection_set[..]),
384384
&mut sub_exec);
385385

386386
if let Ok(Value::Object(mut hash_map)) = sub_result {
@@ -389,13 +389,13 @@ fn resolve_selection_set_into<T, CtxT>(
389389
}
390390
}
391391
else if let Err(e) = sub_result {
392-
sub_exec.push_error(e, start_pos);
392+
sub_exec.push_error(e, start_pos.clone());
393393
}
394394
}
395395
else {
396396
resolve_selection_set_into(
397397
instance,
398-
fragment.selection_set.clone(),
398+
&fragment.selection_set[..],
399399
&mut sub_exec,
400400
result);
401401
}

src/types/containers.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl<T, CtxT> GraphQLType for Option<T> where T: GraphQLType<Context=CtxT> {
1616
registry.build_nullable_type::<T>().into_meta()
1717
}
1818

19-
fn resolve(&self, _: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> Value {
19+
fn resolve(&self, _: Option<&[Selection]>, executor: &Executor<CtxT>) -> Value {
2020
match *self {
2121
Some(ref obj) => executor.resolve_into_value(obj),
2222
None => Value::null(),
@@ -56,7 +56,7 @@ impl<T, CtxT> GraphQLType for Vec<T> where T: GraphQLType<Context=CtxT> {
5656
registry.build_list_type::<T>().into_meta()
5757
}
5858

59-
fn resolve(&self, _: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> Value {
59+
fn resolve(&self, _: Option<&[Selection]>, executor: &Executor<CtxT>) -> Value {
6060
Value::list(
6161
self.iter().map(|e| executor.resolve_into_value(e)).collect()
6262
)
@@ -103,7 +103,7 @@ impl<'a, T, CtxT> GraphQLType for &'a [T] where T: GraphQLType<Context=CtxT> {
103103
registry.build_list_type::<T>().into_meta()
104104
}
105105

106-
fn resolve(&self, _: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> Value {
106+
fn resolve(&self, _: Option<&[Selection]>, executor: &Executor<CtxT>) -> Value {
107107
Value::list(
108108
self.iter().map(|e| executor.resolve_into_value(e)).collect()
109109
)

src/types/pointers.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl<T, CtxT> GraphQLType for Box<T> where T: GraphQLType<Context=CtxT> {
1616
T::meta(registry)
1717
}
1818

19-
fn resolve_into_type(&self, name: &str, selection_set: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> ExecutionResult {
19+
fn resolve_into_type(&self, name: &str, selection_set: Option<&[Selection]>, executor: &Executor<CtxT>) -> ExecutionResult {
2020
(**self).resolve_into_type(name, selection_set, executor)
2121
}
2222

@@ -25,7 +25,7 @@ impl<T, CtxT> GraphQLType for Box<T> where T: GraphQLType<Context=CtxT> {
2525
(**self).resolve_field(field, args, executor)
2626
}
2727

28-
fn resolve(&self, selection_set: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> Value {
28+
fn resolve(&self, selection_set: Option<&[Selection]>, executor: &Executor<CtxT>) -> Value {
2929
(**self).resolve(selection_set, executor)
3030
}
3131
}
@@ -56,7 +56,7 @@ impl<'a, T, CtxT> GraphQLType for &'a T where T: GraphQLType<Context=CtxT> {
5656
T::meta(registry)
5757
}
5858

59-
fn resolve_into_type(&self, name: &str, selection_set: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> ExecutionResult {
59+
fn resolve_into_type(&self, name: &str, selection_set: Option<&[Selection]>, executor: &Executor<CtxT>) -> ExecutionResult {
6060
(**self).resolve_into_type(name, selection_set, executor)
6161
}
6262

@@ -65,7 +65,7 @@ impl<'a, T, CtxT> GraphQLType for &'a T where T: GraphQLType<Context=CtxT> {
6565
(**self).resolve_field(field, args, executor)
6666
}
6767

68-
fn resolve(&self, selection_set: Option<Vec<Selection>>, executor: &Executor<CtxT>) -> Value {
68+
fn resolve(&self, selection_set: Option<&[Selection]>, executor: &Executor<CtxT>) -> Value {
6969
(**self).resolve(selection_set, executor)
7070
}
7171
}

src/types/scalars.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl<'a> GraphQLType for &'a str {
5353
registry.build_scalar_type::<String>().into_meta()
5454
}
5555

56-
fn resolve(&self, _: Option<Vec<Selection>>, _: &Executor<Self::Context>) -> Value {
56+
fn resolve(&self, _: Option<&[Selection]>, _: &Executor<Self::Context>) -> Value {
5757
Value::string(self)
5858
}
5959
}

0 commit comments

Comments
 (0)