Skip to content

Commit c5cd8fe

Browse files
committed
performance improvement of the ast build cache,
uses an empty no-op root for the cached ASTs since their roots are never queried
1 parent 5fd0903 commit c5cd8fe

File tree

8 files changed

+70
-73
lines changed

8 files changed

+70
-73
lines changed

glsl-transformer/src/main/java/io/github/douira/glsl_transformer/ast/node/Identifier.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public void setName(String name) {
2727
return;
2828
}
2929
validateContents(name);
30-
getRoot().identifierIndex.remove(this);
30+
getRoot().unregisterIdentifierRename(this);
3131
this.name = name;
32-
getRoot().identifierIndex.add(this);
32+
getRoot().registerIdentifierRename(this);
3333
}
3434

3535
/**
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.github.douira.glsl_transformer.ast.query;
2+
3+
import io.github.douira.glsl_transformer.ast.node.Identifier;
4+
import io.github.douira.glsl_transformer.ast.node.basic.ASTNode;
5+
6+
/**
7+
* The empty root overrides a normal root just to do nothing. This allows a root
8+
* stub to exist without the performance cost of registering and unregistering
9+
* nodes.
10+
*/
11+
public class EmptyRoot extends Root {
12+
public EmptyRoot() {
13+
super(null, null);
14+
}
15+
16+
@Override
17+
public void registerIdentifierRename(Identifier identifier) {
18+
}
19+
20+
@Override
21+
public void registerNode(ASTNode node) {
22+
}
23+
24+
@Override
25+
public void unregisterIdentifierRename(Identifier identifier) {
26+
}
27+
28+
@Override
29+
public void unregisterNode(ASTNode node) {
30+
}
31+
}

glsl-transformer/src/main/java/io/github/douira/glsl_transformer/ast/query/Root.java

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,30 @@ public class Root {
3333
* query capabilities.
3434
*/
3535
public final IdentifierIndex<?> identifierIndex;
36+
37+
// internal utility state
38+
private static Deque<Root> activeBuildRoots = new ArrayDeque<>();
3639
private List<? extends ASTNode> nodeList;
3740
private boolean activity;
3841

39-
private static Deque<Root> activeBuildRoots = new ArrayDeque<>();
42+
/**
43+
* Constructs a new root with the given node and identifier indexes.
44+
*
45+
* @param nodeIndex The node index
46+
* @param identifierIndex The identifier index
47+
*/
48+
public Root(NodeIndex nodeIndex, IdentifierIndex<?> identifierIndex) {
49+
this.nodeIndex = nodeIndex;
50+
this.identifierIndex = identifierIndex;
51+
}
52+
53+
/**
54+
* Constructs a new root with the default node and identifier indexes which have
55+
* the least amount of functionality but are also the most efficient.
56+
*/
57+
public Root() {
58+
this(new NodeIndex(), IdentifierIndex.withPrefix());
59+
}
4060

4161
/**
4262
* Returns the currently active build root. When nodes are constructed within a
@@ -194,25 +214,6 @@ public static <NodeType extends ASTNode> void indexSeparateTrees(
194214
indexSeparateTrees(treeMember.getRoot(), registerer);
195215
}
196216

197-
/**
198-
* Constructs a new root with the given node and identifier indexes.
199-
*
200-
* @param nodeIndex The node index
201-
* @param identifierIndex The identifier index
202-
*/
203-
public Root(NodeIndex nodeIndex, IdentifierIndex<?> identifierIndex) {
204-
this.nodeIndex = nodeIndex;
205-
this.identifierIndex = identifierIndex;
206-
}
207-
208-
/**
209-
* Constructs a new root with the default node and identifier indexes which have
210-
* the least amount of functionality but are also the most efficient.
211-
*/
212-
public Root() {
213-
this(new NodeIndex(), IdentifierIndex.withPrefix());
214-
}
215-
216217
/**
217218
* Registers the given node with this root.
218219
*
@@ -237,15 +238,12 @@ public void unregisterNode(ASTNode node) {
237238
}
238239
}
239240

240-
/**
241-
* Merges the given root into this root. This will merge the node index and the
242-
* identifier index.
243-
*
244-
* @param other The root to merge into this root
245-
*/
246-
public void merge(Root other) {
247-
nodeIndex.merge(other.nodeIndex);
248-
identifierIndex.merge(other.identifierIndex);
241+
public void unregisterIdentifierRename(Identifier identifier) {
242+
identifierIndex.remove(identifier);
243+
}
244+
245+
public void registerIdentifierRename(Identifier identifier) {
246+
identifierIndex.add(identifier);
249247
}
250248

251249
private void ensureEmptyNodeList() {

glsl-transformer/src/main/java/io/github/douira/glsl_transformer/ast/query/index/IdentifierIndex.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,6 @@ public void remove(Identifier node) {
4444
}
4545
}
4646

47-
public void merge(IdentifierIndex<?> other) {
48-
for (var entry : other.index.entrySet()) {
49-
var set = index.get(entry.getKey());
50-
if (set == null) {
51-
set = new HashSet<>();
52-
index.put(entry.getKey(), set);
53-
}
54-
set.addAll(entry.getValue());
55-
}
56-
}
57-
5847
public Set<Identifier> get(String k) {
5948
var result = index.get(k);
6049
return result == null ? Collections.emptySet() : result;

glsl-transformer/src/main/java/io/github/douira/glsl_transformer/ast/query/index/NodeIndex.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -165,20 +165,4 @@ public boolean hasExact(ASTNode node) {
165165
var set = get(node);
166166
return set != null && set.contains(node);
167167
}
168-
169-
/**
170-
* Merges the given node index into this one.
171-
*
172-
* @param other the other index to merge
173-
*/
174-
public void merge(NodeIndex other) {
175-
for (var entry : other.index.entrySet()) {
176-
var set = (Set<ASTNode>) index.get(entry.getKey());
177-
if (set == null) {
178-
set = bucketConstructor.get();
179-
index.put(entry.getKey(), set);
180-
}
181-
set.addAll(entry.getValue());
182-
}
183-
}
184168
}

glsl-transformer/src/main/java/io/github/douira/glsl_transformer/ast/transform/ASTBuilder.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ public static <TreeType extends ParseTree, ReturnType extends ASTNode> ReturnTyp
8080
return Root.indexNodes(() -> buildInternal(ctx, visitMethod));
8181
}
8282

83+
public static <TreeType extends ParseTree, ReturnType extends ASTNode> ReturnType build(
84+
Root rootInstance,
85+
TreeType ctx,
86+
BiFunction<ASTBuilder, TreeType, ReturnType> visitMethod) {
87+
return Root.indexNodes(rootInstance, () -> buildInternal(ctx, visitMethod));
88+
}
89+
8390
/**
8491
* Builds a subtree that has the same root as the given AST node.
8592
*

glsl-transformer/src/main/java/io/github/douira/glsl_transformer/ast/transform/ASTParser.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import io.github.douira.glsl_transformer.ast.node.expression.Expression;
1414
import io.github.douira.glsl_transformer.ast.node.external_declaration.ExternalDeclaration;
1515
import io.github.douira.glsl_transformer.ast.node.statement.Statement;
16+
import io.github.douira.glsl_transformer.ast.query.EmptyRoot;
1617
import io.github.douira.glsl_transformer.basic.*;
1718
import io.github.douira.glsl_transformer.basic.EnhancedParser.ParsingStrategy;
1819
import io.github.douira.glsl_transformer.cst.token_filter.TokenFilter;
@@ -106,7 +107,7 @@ public <RuleType extends ExtendedContext, ReturnType extends ASTNode> ReturnType
106107
} else {
107108
// cache and possibly build, always clone to return new trees
108109
return (ReturnType) buildCache.cachedGet(input, ruleType,
109-
() -> ASTBuilder.build(parser.parse(input, ruleType, parseMethod), visitMethod))
110+
() -> ASTBuilder.build(new EmptyRoot(), parser.parse(input, ruleType, parseMethod), visitMethod))
110111
.cloneInto(parentTreeMember);
111112
}
112113
}
@@ -123,7 +124,7 @@ public <RuleType extends ExtendedContext, ReturnType extends ASTNode> ReturnType
123124
return ASTBuilder.build(parser.parse(input, ruleType, parseMethod), visitMethod);
124125
} else {
125126
return (ReturnType) buildCache.cachedGet(input, ruleType,
126-
() -> ASTBuilder.build(parser.parse(input, ruleType, parseMethod), visitMethod))
127+
() -> ASTBuilder.build(new EmptyRoot(), parser.parse(input, ruleType, parseMethod), visitMethod))
127128
.cloneSeparate();
128129
}
129130
}

glsl-transformer/src/test/java/io/github/douira/glsl_transformer/ast/query/NodeIndexTest.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,6 @@ void testHasExact() {
9090
assertFalse(index.hasExact(new Identifier("e")));
9191
}
9292

93-
@Test
94-
void testMerge() {
95-
var other = new NodeIndex();
96-
other.add(a);
97-
other.add(b);
98-
var e = new Identifier("e");
99-
other.add(e);
100-
index.add(a);
101-
index.add(c);
102-
index.merge(other);
103-
assertEquals(Set.of(a, b, e, c), index.get(Identifier.class));
104-
}
105-
10693
@Test
10794
void testRemove() {
10895
index.add(a);

0 commit comments

Comments
 (0)