Skip to content

Commit 90cbde4

Browse files
committed
Avoid unnecessary (and expensive) work when matching path wildcards. (#207, #97)
`SimpleRegexTrie` is only used to determine whether a field name matches a pattern. The result of this computation only depends on these two values, not on the underlying data. So we can cache and reuse the result across the whole transformation process. It might be possible to implement the matching in a more optimized way for this particular use case, but it's delegated to `SimpleRegexTrie` for compatibility and maintainability purposes.
1 parent 1ecbcdf commit 90cbde4

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

metafix/src/main/java/org/metafacture/metafix/Value.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.ArrayList;
2222
import java.util.Collection;
2323
import java.util.ConcurrentModificationException;
24+
import java.util.HashMap;
2425
import java.util.HashSet;
2526
import java.util.LinkedHashMap;
2627
import java.util.List;
@@ -459,9 +460,10 @@ public void remove(final int index) {
459460
*/
460461
public static class Hash extends AbstractValueType {
461462

462-
private final Map<String, Value> map = new LinkedHashMap<>();
463+
private static final Map<String, Map<String, Boolean>> TRIE_CACHE = new HashMap<>();
464+
private static final SimpleRegexTrie<String> TRIE = new SimpleRegexTrie<>();
463465

464-
private final SimpleRegexTrie<String> trie = new SimpleRegexTrie<>();
466+
private final Map<String, Value> map = new LinkedHashMap<>();
465467

466468
/**
467469
* Creates an empty instance of {@link Hash}.
@@ -695,8 +697,12 @@ private Stream<String> findFields(final String pattern) {
695697
}
696698

697699
private <T> T matchFields(final String pattern, final BiFunction<Stream<String>, Predicate<String>, T> function) {
698-
trie.put(pattern, pattern);
699-
return function.apply(map.keySet().stream(), f -> trie.get(f).contains(pattern));
700+
final Map<String, Boolean> matcher = TRIE_CACHE.computeIfAbsent(pattern, k -> {
701+
TRIE.put(k, k);
702+
return new HashMap<>();
703+
});
704+
705+
return function.apply(map.keySet().stream(), f -> matcher.computeIfAbsent(f, k -> TRIE.get(k).contains(pattern)));
700706
}
701707

702708
}

metafix/src/test/java/org/metafacture/metafix/HashValueTest.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package org.metafacture.metafix;
1818

19-
import org.metafacture.commons.tries.SimpleRegexTrie;
20-
2119
import nl.jqno.equalsverifier.EqualsVerifier;
2220
import org.junit.jupiter.api.Assertions;
2321
import org.junit.jupiter.api.Test;
@@ -46,8 +44,6 @@ public HashValueTest() {
4644
public void shouldSatisfyEqualsContract() {
4745
EqualsVerifier.forClass(Value.Hash.class)
4846
.withPrefabValues(Value.class, Value.newArray(), Value.newHash())
49-
.withPrefabValues(SimpleRegexTrie.class, new SimpleRegexTrie<String>(), new SimpleRegexTrie<String>())
50-
.withIgnoredFields("trie")
5147
.verify();
5248
}
5349

0 commit comments

Comments
 (0)