Skip to content

Commit

Permalink
perf: allow skipping of field plan generation (#4050)
Browse files Browse the repository at this point in the history
in the non-deferred case.

depends on #4026

---------

Co-authored-by: Rob Richard <[email protected]>
  • Loading branch information
yaacovCR and robrichard authored Apr 19, 2024
1 parent 05e7a29 commit 6d777e6
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 212 deletions.
79 changes: 20 additions & 59 deletions src/execution/buildFieldPlan.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,39 @@
import { getBySet } from '../jsutils/getBySet.js';
import { isSameSet } from '../jsutils/isSameSet.js';

import type { DeferUsage, FieldDetails } from './collectFields.js';
import type {
DeferUsage,
FieldGroup,
GroupedFieldSet,
} from './collectFields.js';

export type DeferUsageSet = ReadonlySet<DeferUsage>;

export interface FieldGroup {
fields: ReadonlyArray<FieldDetails>;
deferUsages?: DeferUsageSet | undefined;
export interface FieldPlan {
groupedFieldSet: GroupedFieldSet;
newGroupedFieldSets: Map<DeferUsageSet, GroupedFieldSet>;
}

export type GroupedFieldSet = Map<string, FieldGroup>;

export function buildFieldPlan(
fields: Map<string, ReadonlyArray<FieldDetails>>,
originalGroupedFieldSet: GroupedFieldSet,
parentDeferUsages: DeferUsageSet = new Set<DeferUsage>(),
): {
groupedFieldSet: GroupedFieldSet;
newGroupedFieldSets: Map<DeferUsageSet, GroupedFieldSet>;
} {
const groupedFieldSet = new Map<
string,
{
fields: Array<FieldDetails>;
deferUsages: DeferUsageSet;
}
>();
): FieldPlan {
const groupedFieldSet = new Map<string, FieldGroup>();

const newGroupedFieldSets = new Map<
DeferUsageSet,
Map<
string,
{
fields: Array<FieldDetails>;
deferUsages: DeferUsageSet;
}
>
>();
const newGroupedFieldSets = new Map<DeferUsageSet, Map<string, FieldGroup>>();

const map = new Map<
string,
{
deferUsageSet: DeferUsageSet;
fieldDetailsList: ReadonlyArray<FieldDetails>;
fieldGroup: FieldGroup;
}
>();

for (const [responseKey, fieldDetailsList] of fields) {
for (const [responseKey, fieldGroup] of originalGroupedFieldSet) {
const deferUsageSet = new Set<DeferUsage>();
let inOriginalResult = false;
for (const fieldDetails of fieldDetailsList) {
for (const fieldDetails of fieldGroup) {
const deferUsage = fieldDetails.deferUsage;
if (deferUsage === undefined) {
inOriginalResult = true;
Expand All @@ -69,44 +53,21 @@ export function buildFieldPlan(
}
});
}
map.set(responseKey, { deferUsageSet, fieldDetailsList });
map.set(responseKey, { deferUsageSet, fieldGroup });
}

for (const [responseKey, { deferUsageSet, fieldDetailsList }] of map) {
for (const [responseKey, { deferUsageSet, fieldGroup }] of map) {
if (isSameSet(deferUsageSet, parentDeferUsages)) {
let fieldGroup = groupedFieldSet.get(responseKey);
if (fieldGroup === undefined) {
fieldGroup = {
fields: [],
deferUsages: deferUsageSet,
};
groupedFieldSet.set(responseKey, fieldGroup);
}
fieldGroup.fields.push(...fieldDetailsList);
groupedFieldSet.set(responseKey, fieldGroup);
continue;
}

let newGroupedFieldSet = getBySet(newGroupedFieldSets, deferUsageSet);
if (newGroupedFieldSet === undefined) {
newGroupedFieldSet = new Map<
string,
{
fields: Array<FieldDetails>;
deferUsages: DeferUsageSet;
knownDeferUsages: DeferUsageSet;
}
>();
newGroupedFieldSet = new Map();
newGroupedFieldSets.set(deferUsageSet, newGroupedFieldSet);
}
let fieldGroup = newGroupedFieldSet.get(responseKey);
if (fieldGroup === undefined) {
fieldGroup = {
fields: [],
deferUsages: deferUsageSet,
};
newGroupedFieldSet.set(responseKey, fieldGroup);
}
fieldGroup.fields.push(...fieldDetailsList);
newGroupedFieldSet.set(responseKey, fieldGroup);
}

return {
Expand Down
16 changes: 10 additions & 6 deletions src/execution/collectFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export interface FieldDetails {
deferUsage: DeferUsage | undefined;
}

export type FieldGroup = ReadonlyArray<FieldDetails>;

export type GroupedFieldSet = ReadonlyMap<string, FieldGroup>;

interface CollectFieldsContext {
schema: GraphQLSchema;
fragments: ObjMap<FragmentDefinitionNode>;
Expand All @@ -61,7 +65,7 @@ export function collectFields(
runtimeType: GraphQLObjectType,
operation: OperationDefinitionNode,
): {
fields: Map<string, ReadonlyArray<FieldDetails>>;
groupedFieldSet: GroupedFieldSet;
newDeferUsages: ReadonlyArray<DeferUsage>;
} {
const groupedFieldSet = new AccumulatorMap<string, FieldDetails>();
Expand All @@ -81,7 +85,7 @@ export function collectFields(
groupedFieldSet,
newDeferUsages,
);
return { fields: groupedFieldSet, newDeferUsages };
return { groupedFieldSet, newDeferUsages };
}

/**
Expand All @@ -101,9 +105,9 @@ export function collectSubfields(
variableValues: { [variable: string]: unknown },
operation: OperationDefinitionNode,
returnType: GraphQLObjectType,
fieldDetails: ReadonlyArray<FieldDetails>,
fieldGroup: FieldGroup,
): {
fields: Map<string, ReadonlyArray<FieldDetails>>;
groupedFieldSet: GroupedFieldSet;
newDeferUsages: ReadonlyArray<DeferUsage>;
} {
const context: CollectFieldsContext = {
Expand All @@ -117,7 +121,7 @@ export function collectSubfields(
const subGroupedFieldSet = new AccumulatorMap<string, FieldDetails>();
const newDeferUsages: Array<DeferUsage> = [];

for (const fieldDetail of fieldDetails) {
for (const fieldDetail of fieldGroup) {
const node = fieldDetail.node;
if (node.selectionSet) {
collectFieldsImpl(
Expand All @@ -131,7 +135,7 @@ export function collectSubfields(
}

return {
fields: subGroupedFieldSet,
groupedFieldSet: subGroupedFieldSet,
newDeferUsages,
};
}
Expand Down
Loading

0 comments on commit 6d777e6

Please sign in to comment.