Skip to content

Commit

Permalink
Make enum addValue() faster by using an Map rather than an array (#3045)
Browse files Browse the repository at this point in the history
Merging enums was previously a O(n^3) operation.
  • Loading branch information
clenfest authored Jun 24, 2024
1 parent b2e5ab6 commit eb81831
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions internals-js/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2291,19 +2291,19 @@ export class UnionType extends BaseNamedType<OutputTypeReferencer, UnionType> {
export class EnumType extends BaseNamedType<OutputTypeReferencer, EnumType> {
readonly kind = 'EnumType' as const;
readonly astDefinitionKind = Kind.ENUM_TYPE_DEFINITION;
protected readonly _values: EnumValue[] = [];
private _values = new Map<string, EnumValue>();

get values(): readonly EnumValue[] {
// Because our abstractions are mutable, and removal is done by calling
// `remove()` on the element to remove, it's not unlikely someone mauy
// try to iterate on the result of this method and call `remove()` on
// some of the return value based on some condition. But this will break
// in an error-prone way if we don't copy, so we do.
return Array.from(this._values);
return Array.from(this._values.values());
}

value(name: string): EnumValue | undefined {
return this._values.find(v => v.name === name);
return this._values.get(name);
}

addValue(value: EnumValue): EnumValue;
Expand All @@ -2319,7 +2319,7 @@ export class EnumType extends BaseNamedType<OutputTypeReferencer, EnumType> {
}
const existing = this.value(toAdd.name);
if (!existing) {
this._values.push(toAdd);
this._values.set(toAdd.name, toAdd);
Element.prototype['setParent'].call(toAdd, this);
this.onModification();
return toAdd;
Expand All @@ -2333,7 +2333,7 @@ export class EnumType extends BaseNamedType<OutputTypeReferencer, EnumType> {
}

private removeValueInternal(value: EnumValue) {
removeArrayElement(value, this._values);
this._values.delete(value.name);
}

protected removeInnerElements(): void {
Expand All @@ -2345,15 +2345,17 @@ export class EnumType extends BaseNamedType<OutputTypeReferencer, EnumType> {
}

protected hasNonExtensionInnerElements(): boolean {
return this._values.some(v => v.ofExtension() === undefined);
return Array.from(this._values.values()).some(v => v.ofExtension() === undefined);
}

protected removeReferenceRecursive(ref: OutputTypeReferencer): void {
ref.removeRecursive();
}

protected removeInnerElementsExtensions(): void {
this._values.forEach(v => v.removeOfExtension());
for (const v of this._values.values()) {
v.removeOfExtension();
}
}
}

Expand Down

0 comments on commit eb81831

Please sign in to comment.