Skip to content

Commit

Permalink
Remove excessive cache inside lexicographicSortSchema (#1681)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov authored Jan 22, 2019
1 parent bdfd1c6 commit c2bc19b
Showing 1 changed file with 35 additions and 36 deletions.
71 changes: 35 additions & 36 deletions src/utilities/lexicographicSortSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
* @flow strict
*/

import objectValues from '../polyfills/objectValues';
import keyValMap from '../jsutils/keyValMap';
import type { ObjMap } from '../jsutils/ObjMap';
import { GraphQLSchema } from '../type/schema';
import { GraphQLDirective } from '../type/directives';
Expand All @@ -28,26 +30,45 @@ import {
isEnumType,
isInputObjectType,
} from '../type/definition';
import { isSpecifiedScalarType } from '../type/scalars';
import { isIntrospectionType } from '../type/introspection';

/**
* Sort GraphQLSchema.
*/
export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema {
const cache = Object.create(null);

const schemaConfig = schema.toConfig();
const sortMaybeType = maybeType => maybeType && sortNamedType(maybeType);
const typeMap = keyValMap(
sortByName(schemaConfig.types),
type => type.name,
sortNamedType,
);

return new GraphQLSchema({
...schemaConfig,
types: sortTypes(schemaConfig.types),
types: objectValues(typeMap),
directives: sortByName(schemaConfig.directives).map(sortDirective),
query: sortMaybeType(schemaConfig.query),
mutation: sortMaybeType(schemaConfig.mutation),
subscription: sortMaybeType(schemaConfig.subscription),
query: replaceMaybeType(schemaConfig.query),
mutation: replaceMaybeType(schemaConfig.mutation),
subscription: replaceMaybeType(schemaConfig.subscription),
});

function replaceType(type) {
if (isListType(type)) {
return new GraphQLList(replaceType(type.ofType));
} else if (isNonNullType(type)) {
return new GraphQLNonNull(replaceType(type.ofType));
}
return replaceNamedType(type);
}

function replaceNamedType<T: GraphQLNamedType>(type: T): T {
return ((typeMap[type.name]: any): T);
}

function replaceMaybeType(maybeType) {
return maybeType && replaceNamedType(maybeType);
}

function sortDirective(directive) {
const config = directive.toConfig();
return new GraphQLDirective({
Expand All @@ -60,53 +81,31 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema {
function sortArgs(args) {
return sortObjMap(args, arg => ({
...arg,
type: sortType(arg.type),
type: replaceType(arg.type),
}));
}

function sortFields(fieldsMap) {
return sortObjMap(fieldsMap, field => ({
...field,
type: sortType(field.type),
type: replaceType(field.type),
args: sortArgs(field.args),
}));
}

function sortInputFields(fieldsMap) {
return sortObjMap(fieldsMap, field => ({
...field,
type: sortType(field.type),
type: replaceType(field.type),
}));
}

function sortType(type) {
if (isListType(type)) {
return new GraphQLList(sortType(type.ofType));
} else if (isNonNullType(type)) {
return new GraphQLNonNull(sortType(type.ofType));
}
return sortNamedType(type);
}

function sortTypes<T: GraphQLNamedType>(arr: Array<T>): Array<T> {
return sortByName(arr).map(sortNamedType);
}

function sortNamedType<T: GraphQLNamedType>(type: T): T {
if (isSpecifiedScalarType(type) || isIntrospectionType(type)) {
return type;
}

let sortedType = cache[type.name];
if (!sortedType) {
sortedType = sortNamedTypeImpl(type);
cache[type.name] = sortedType;
}
return ((sortedType: any): T);
return sortByName(arr).map(replaceNamedType);
}

function sortNamedTypeImpl(type) {
if (isScalarType(type)) {
function sortNamedType(type) {
if (isScalarType(type) || isIntrospectionType(type)) {
return type;
} else if (isObjectType(type)) {
const config = type.toConfig();
Expand Down

0 comments on commit c2bc19b

Please sign in to comment.