Skip to content

Commit 4612e99

Browse files
committed
bring the memoized subfield collector into the class
1 parent 128b790 commit 4612e99

File tree

4 files changed

+59
-74
lines changed

4 files changed

+59
-74
lines changed

src/execution/Executor.ts

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { invariant } from '../jsutils/invariant.js';
44
import { isAsyncIterable } from '../jsutils/isAsyncIterable.js';
55
import { isIterableObject } from '../jsutils/isIterableObject.js';
66
import { isPromise } from '../jsutils/isPromise.js';
7-
import { memoize3 } from '../jsutils/memoize3.js';
7+
import { memoize2 } from '../jsutils/memoize2.js';
88
import type { ObjMap } from '../jsutils/ObjMap.js';
99
import type { Path } from '../jsutils/Path.js';
1010
import { addPath, pathToArray } from '../jsutils/Path.js';
@@ -56,10 +56,7 @@ import type {
5656
FragmentDetails,
5757
GroupedFieldSet,
5858
} from './collectFields.js';
59-
import {
60-
collectFields,
61-
collectSubfields as _collectSubfields,
62-
} from './collectFields.js';
59+
import { collectFields, collectSubfields } from './collectFields.js';
6360
import { buildIncrementalResponse } from './IncrementalPublisher.js';
6461
import type {
6562
CancellableStreamRecord,
@@ -80,30 +77,6 @@ import { experimentalGetArgumentValues, getDirectiveValues } from './values.js';
8077
// This file contains a lot of such errors but we plan to refactor it anyway
8178
// so just disable it for entire file.
8279

83-
/**
84-
* A memoized collection of relevant subfields with regard to the return
85-
* type. Memoizing ensures the subfields are not repeatedly calculated, which
86-
* saves overhead when resolving lists of values.
87-
*/
88-
const collectSubfields = memoize3(
89-
(
90-
validatedExecutionArgs: ValidatedExecutionArgs,
91-
returnType: GraphQLObjectType,
92-
fieldDetailsList: FieldDetailsList,
93-
) => {
94-
const { schema, fragments, variableValues, hideSuggestions } =
95-
validatedExecutionArgs;
96-
return _collectSubfields(
97-
schema,
98-
fragments,
99-
variableValues,
100-
returnType,
101-
fieldDetailsList,
102-
hideSuggestions,
103-
);
104-
},
105-
);
106-
10780
/**
10881
* Terminology
10982
*
@@ -181,6 +154,19 @@ export class Executor {
181154
validatedExecutionArgs: ValidatedExecutionArgs;
182155
exeContext: ExecutionContext;
183156

157+
/**
158+
* A memoized collection of relevant subfields with regard to the return
159+
* type. Memoizing ensures the subfields are not repeatedly calculated, which
160+
* saves overhead when resolving lists of values.
161+
*/
162+
collectSubfields: (
163+
returnType: GraphQLObjectType,
164+
fieldDetailsList: FieldDetailsList,
165+
) => {
166+
groupedFieldSet: GroupedFieldSet;
167+
newDeferUsages: ReadonlyArray<DeferUsage>;
168+
};
169+
184170
constructor(validatedExecutionArgs: ValidatedExecutionArgs) {
185171
this.validatedExecutionArgs = validatedExecutionArgs;
186172
const abortSignal = validatedExecutionArgs.abortSignal;
@@ -192,6 +178,21 @@ export class Executor {
192178
completed: false,
193179
cancellableStreams: undefined,
194180
};
181+
182+
const { schema, fragments, variableValues, hideSuggestions } =
183+
validatedExecutionArgs;
184+
185+
this.collectSubfields = memoize2(
186+
(returnType: GraphQLObjectType, fieldDetailsList: FieldDetailsList) =>
187+
collectSubfields(
188+
schema,
189+
fragments,
190+
variableValues,
191+
returnType,
192+
fieldDetailsList,
193+
hideSuggestions,
194+
),
195+
);
195196
}
196197

197198
executeQueryOrMutationOrSubscriptionEvent(): PromiseOrValue<
@@ -1575,8 +1576,7 @@ export class Executor {
15751576
deferMap: ReadonlyMap<DeferUsage, DeferredFragmentRecord> | undefined,
15761577
): PromiseOrValue<GraphQLWrappedResult<ObjMap<unknown>>> {
15771578
// Collect sub-fields to execute to complete this value.
1578-
const collectedSubfields = collectSubfields(
1579-
this.validatedExecutionArgs,
1579+
const collectedSubfields = this.collectSubfields(
15801580
returnType,
15811581
fieldDetailsList,
15821582
);

src/execution/execute.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,6 @@ export function executeSync(args: ExecutionArgs): ExecutionResult {
191191
}
192192

193193
/**
194-
* Constructs a ExecutionContext object from the arguments passed to
195-
* execute, which we will pass throughout the other execution methods.
196-
*
197-
* Throws a GraphQLError if a valid execution context cannot be created.
198-
*
199-
* TODO: consider no longer exporting this function
200194
* @internal
201195
*/
202196
export function validateExecutionArgs(

src/jsutils/memoize2.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Memoizes the provided two-argument function.
3+
*/
4+
export function memoize2<A1 extends object, A2 extends object, R>(
5+
fn: (a1: A1, a2: A2) => R,
6+
): (a1: A1, a2: A2) => R {
7+
let cache0: WeakMap<A1, WeakMap<A2, R>>;
8+
9+
return function memoized(a1, a2) {
10+
if (cache0 === undefined) {
11+
cache0 = new WeakMap();
12+
}
13+
14+
let cache1 = cache0.get(a1);
15+
if (cache1 === undefined) {
16+
cache1 = new WeakMap();
17+
cache0.set(a1, cache1);
18+
}
19+
20+
let fnResult = cache1.get(a2);
21+
if (fnResult === undefined) {
22+
fnResult = fn(a1, a2);
23+
cache1.set(a2, fnResult);
24+
}
25+
26+
return fnResult;
27+
};
28+
}

src/jsutils/memoize3.ts

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)