Skip to content

Commit 894583c

Browse files
committed
Include context in memoization, Factor out memoize3
1 parent 2eba17d commit 894583c

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

src/execution/execute.js

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { GraphQLError, locatedError } from '../error';
1212
import invariant from '../jsutils/invariant';
1313
import isInvalid from '../jsutils/isInvalid';
1414
import isNullish from '../jsutils/isNullish';
15+
import memoize3 from '../jsutils/memoize3';
1516
import type { ObjMap } from '../jsutils/ObjMap';
1617
import type { MaybePromise } from '../jsutils/MaybePromise';
1718

@@ -1245,25 +1246,12 @@ function collectAndExecuteSubfields(
12451246
* type. Memoizing ensures the subfields are not repeatedly calculated, which
12461247
* saves overhead when resolving lists of values.
12471248
*/
1248-
const subfieldCache: WeakMap<
1249-
$ReadOnlyArray<FieldNode>,
1250-
WeakMap<GraphQLObjectType, ObjMap<Array<FieldNode>>>,
1251-
> = new WeakMap();
1252-
function collectSubfields(
1249+
const collectSubfields = memoize3(_collectSubfields);
1250+
function _collectSubfields(
12531251
exeContext: ExecutionContext,
12541252
returnType: GraphQLObjectType,
12551253
fieldNodes: $ReadOnlyArray<FieldNode>,
12561254
): ObjMap<Array<FieldNode>> {
1257-
let cacheByReturnType = subfieldCache.get(fieldNodes);
1258-
if (cacheByReturnType) {
1259-
const cachedSubFieldNodes = cacheByReturnType.get(returnType);
1260-
if (cachedSubFieldNodes) {
1261-
return cachedSubFieldNodes;
1262-
}
1263-
} else {
1264-
cacheByReturnType = new WeakMap();
1265-
subfieldCache.set(fieldNodes, cacheByReturnType);
1266-
}
12671255
let subFieldNodes = Object.create(null);
12681256
const visitedFragmentNames = Object.create(null);
12691257
for (let i = 0; i < fieldNodes.length; i++) {
@@ -1278,7 +1266,6 @@ function collectSubfields(
12781266
);
12791267
}
12801268
}
1281-
cacheByReturnType.set(returnType, subFieldNodes);
12821269
return subFieldNodes;
12831270
}
12841271

src/jsutils/memoize3.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Copyright (c) 2017-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
/**
11+
* Memoizes the provided three-argument function.
12+
*/
13+
export default function memoize3<T: (a1: any, a2: any, a3: any) => any>(
14+
fn: T,
15+
): T {
16+
let cache0;
17+
function memoized(a1, a2, a3) {
18+
if (!cache0) {
19+
cache0 = new WeakMap();
20+
}
21+
let cache1 = cache0.get(a1);
22+
let cache2;
23+
if (cache1) {
24+
cache2 = cache1.get(a2);
25+
if (cache2) {
26+
const cachedValue = cache2.get(a3);
27+
if (cachedValue) {
28+
return cachedValue;
29+
}
30+
}
31+
} else {
32+
cache1 = new WeakMap();
33+
cache0.set(a1, cache1);
34+
}
35+
if (!cache2) {
36+
cache2 = new WeakMap();
37+
cache1.set(a2, cache2);
38+
}
39+
const newValue = fn.apply(this, arguments);
40+
cache2.set(a3, newValue);
41+
return newValue;
42+
}
43+
return (memoized: any);
44+
}

0 commit comments

Comments
 (0)