|
46 | 46 | import java.util.Set; |
47 | 47 | import java.util.TreeMap; |
48 | 48 | import java.util.concurrent.ConcurrentHashMap; |
| 49 | +import java.util.concurrent.atomic.AtomicReference; |
49 | 50 | import java.util.function.BiFunction; |
50 | 51 | import java.util.function.Function; |
51 | 52 | import java.util.function.IntFunction; |
@@ -1617,10 +1618,12 @@ public <T> T getConfigMapping(final Class<T> type, final String prefix) { |
1617 | 1618 | * {@inheritDoc} |
1618 | 1619 | * |
1619 | 1620 | * This implementation caches the list of property names collected when {@link SmallRyeConfig} is built via |
1620 | | - * {@link SmallRyeConfigBuilder#build()}. |
| 1621 | + * {@link SmallRyeConfigBuilder#build()}. The cache may be disabled with |
| 1622 | + * {@link SmallRyeConfigBuilder#isCachePropertyNames()}. |
1621 | 1623 | * |
1622 | 1624 | * @return the cached names of all configured keys of the underlying configuration |
1623 | 1625 | * @see SmallRyeConfig#getLatestPropertyNames() |
| 1626 | + * @see SmallRyeConfigBuilder#isCachePropertyNames() |
1624 | 1627 | */ |
1625 | 1628 | @Override |
1626 | 1629 | public Iterable<String> getPropertyNames() { |
@@ -1936,7 +1939,7 @@ public Iterator<String> get() { |
1936 | 1939 | this.sources = configSources; |
1937 | 1940 | this.defaultValues = defaultValues; |
1938 | 1941 | this.interceptorChain = current; |
1939 | | - this.propertyNames = new PropertyNames(current, builder.getSecretKeys()); |
| 1942 | + this.propertyNames = new PropertyNames(current, builder.getSecretKeys(), builder.isCachePropertyNames()); |
1940 | 1943 | } |
1941 | 1944 |
|
1942 | 1945 | private static List<ConfigSource> buildSources(final SmallRyeConfigBuilder builder) { |
@@ -2118,33 +2121,36 @@ private static class PropertyNames implements Serializable { |
2118 | 2121 |
|
2119 | 2122 | private final SmallRyeConfigSourceInterceptorContext interceptorChain; |
2120 | 2123 | private final Set<PropertyName> secretKeys; |
| 2124 | + private final boolean cachePropertyNames; |
2121 | 2125 |
|
2122 | | - private final Set<String> names = new HashSet<>(); |
2123 | | - private final Set<String> secretNames = new HashSet<>(); |
2124 | | - private final Map<String, Map<Integer, String>> indexed = new HashMap<>(); |
| 2126 | + private final AtomicReference<Names> names = new AtomicReference<>(Names.empty()); |
2125 | 2127 |
|
2126 | | - public PropertyNames(final SmallRyeConfigSourceInterceptorContext interceptorChain, |
2127 | | - final Set<PropertyName> secretKeys) { |
| 2128 | + public PropertyNames( |
| 2129 | + final SmallRyeConfigSourceInterceptorContext interceptorChain, |
| 2130 | + final Set<PropertyName> secretKeys, |
| 2131 | + final boolean cachePropertyNames) { |
2128 | 2132 | this.interceptorChain = interceptorChain; |
2129 | 2133 | this.secretKeys = secretKeys; |
| 2134 | + this.cachePropertyNames = cachePropertyNames; |
2130 | 2135 | } |
2131 | 2136 |
|
2132 | 2137 | Iterable<String> get() { |
2133 | | - if (names.isEmpty() && secretNames.isEmpty()) { |
| 2138 | + if (!cachePropertyNames || names.get().isEmpty()) { |
2134 | 2139 | return latest(); |
2135 | 2140 | } |
2136 | | - return new Names(); |
| 2141 | + return new NamesIterable(names.get()); |
2137 | 2142 | } |
2138 | 2143 |
|
2139 | 2144 | Map<String, Map<Integer, String>> indexed() { |
2140 | 2145 | // ensure populated |
2141 | 2146 | get(); |
2142 | | - return indexed; |
| 2147 | + return names.get().indexed(); |
2143 | 2148 | } |
2144 | 2149 |
|
2145 | 2150 | Iterable<String> latest() { |
2146 | | - names.clear(); |
2147 | | - secretNames.clear(); |
| 2151 | + Set<String> names = new HashSet<>(); |
| 2152 | + Set<String> secretNames = new HashSet<>(); |
| 2153 | + Map<String, Map<Integer, String>> indexed = new HashMap<>(); |
2148 | 2154 | Iterator<String> namesIterator = interceptorChain.iterateNames(); |
2149 | 2155 | while (namesIterator.hasNext()) { |
2150 | 2156 | String name = namesIterator.next(); |
@@ -2179,32 +2185,53 @@ public String apply(final Integer key, final String value) { |
2179 | 2185 | } |
2180 | 2186 | } |
2181 | 2187 | names.remove(ConfigSource.CONFIG_ORDINAL); |
2182 | | - return new Names(); |
| 2188 | + Names all = new Names(names, secretNames, indexed); |
| 2189 | + if (cachePropertyNames) { |
| 2190 | + this.names.compareAndSet(this.names.get(), all); |
| 2191 | + return new NamesIterable(this.names.get()); |
| 2192 | + } else { |
| 2193 | + return new NamesIterable(all); |
| 2194 | + } |
| 2195 | + } |
| 2196 | + |
| 2197 | + private record Names( |
| 2198 | + Set<String> names, |
| 2199 | + Set<String> secretNames, |
| 2200 | + Map<String, Map<Integer, String>> indexed) { |
| 2201 | + |
| 2202 | + boolean isEmpty() { |
| 2203 | + return names.isEmpty() && secretNames.isEmpty() && indexed.isEmpty(); |
| 2204 | + } |
| 2205 | + |
| 2206 | + static Names empty() { |
| 2207 | + return new Names(Collections.emptySet(), Collections.emptySet(), Collections.emptyMap()); |
| 2208 | + } |
2183 | 2209 | } |
2184 | 2210 |
|
2185 | | - private class Names implements Iterable<String> { |
2186 | | - private final Iterator<Set<String>> names; |
| 2211 | + private static class NamesIterable implements Iterable<String> { |
| 2212 | + private final Iterator<Set<String>> namesIterators; |
2187 | 2213 |
|
2188 | | - public Names() { |
| 2214 | + public NamesIterable(final Names names) { |
2189 | 2215 | if (SecretKeys.isLocked()) { |
2190 | | - this.names = List.of(PropertyNames.this.names).iterator(); |
| 2216 | + this.namesIterators = List.of(names.names()).iterator(); |
2191 | 2217 | } else { |
2192 | | - this.names = List.of(PropertyNames.this.names, PropertyNames.this.secretNames).iterator(); |
| 2218 | + this.namesIterators = List.of(names.names(), names.secretNames()).iterator(); |
2193 | 2219 | } |
2194 | 2220 | } |
2195 | 2221 |
|
2196 | 2222 | @Override |
| 2223 | + @SuppressWarnings("NullableProblems") |
2197 | 2224 | public Iterator<String> iterator() { |
2198 | 2225 | return new Iterator<>() { |
2199 | | - Iterator<String> current = names.next().iterator(); |
| 2226 | + Iterator<String> current = namesIterators.next().iterator(); |
2200 | 2227 |
|
2201 | 2228 | @Override |
2202 | 2229 | public boolean hasNext() { |
2203 | 2230 | if (current.hasNext()) { |
2204 | 2231 | return true; |
2205 | 2232 | } else { |
2206 | | - if (names.hasNext()) { |
2207 | | - current = names.next().iterator(); |
| 2233 | + if (namesIterators.hasNext()) { |
| 2234 | + current = namesIterators.next().iterator(); |
2208 | 2235 | return current.hasNext(); |
2209 | 2236 | } else { |
2210 | 2237 | return false; |
|
0 commit comments