A more memory efficient directives container by bbakerman · Pull Request #4027 · graphql-java/graphql-java · GitHub
Skip to content

A more memory efficient directives container#4027

Merged
bbakerman merged 1 commit intomasterfrom
immutable-language-directive-containers
Jul 4, 2025
Merged

A more memory efficient directives container#4027
bbakerman merged 1 commit intomasterfrom
immutable-language-directive-containers

Conversation

@bbakerman
Copy link
Copy Markdown
Member

When we wrote the graphql.language.DirectivesContainer we put default methods on it to save code in each language element that implemented it

But because interfaces cant have state, then it we doing a per "group by" etc... when each call was made.

This introduces a DirectivesHolder helper class (like we do in the runtime via graphql.DirectivesUtil.DirectivesHolder) that holds the immutable state and helps each implementing class implement the DirectivesContainer methods

So while there is more code in each, it more efficient than the default interface methods

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was terribly memory inefficient

* @return the directives or empty list if there is not one with that name
*/
default List<Directive> getDirectives(String directiveName) {
return getDirectivesByName().getOrDefault(directiveName, emptyList());
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was terribly memory inefficient

* @return true if the AST node contains one or more directives by the specified name
*/
default boolean hasDirective(String directiveName) {
return !getDirectives(directiveName).isEmpty();
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was terribly memory inefficient

@@ -34,20 +34,16 @@ public interface DirectivesContainer<T extends DirectivesContainer> extends Node
*
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer have default methods - but rather a memory efficient DirectivesHolder helper

NodeChildrenContainer newChildren = namedChildren.transform(builder -> builder.removeChild(childLocationToRemove.getName(), childLocationToRemove.getIndex()));
return node.withNewChildren(newChildren);
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our new helper thats immutable and more memory efficient

@github-actions
Copy link
Copy Markdown
Contributor

Copy link
Copy Markdown

@xuorig xuorig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌 perfect

@bbakerman bbakerman merged commit 309fa9d into master Jul 4, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants