Skip to content

Commit 1675da2

Browse files
authored
perf: simplify CacheApiSettings singleton creation (#316)
1 parent 3a2266e commit 1675da2

File tree

2 files changed

+31
-26
lines changed

2 files changed

+31
-26
lines changed

core/src/main/java/io/github/xanthic/cache/core/CacheApiSettings.java

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
*/
2424
@Slf4j
2525
public final class CacheApiSettings {
26-
private static volatile CacheApiSettings INSTANCE;
27-
2826
private final Map<Class<? extends CacheProvider>, CacheProvider> providers = Collections.synchronizedMap(new IdentityHashMap<>(16));
2927
private final AtomicReference<Class<? extends CacheProvider>> defaultCacheProvider = new AtomicReference<>();
3028

@@ -38,7 +36,7 @@ public final class CacheApiSettings {
3836
private volatile MisconfigurationPolicy defaultMisconfigurationPolicy = MisconfigurationPolicy.IGNORE;
3937

4038
private CacheApiSettings() {
41-
// restrict instantiation
39+
this.populateProviders();
4240
}
4341

4442
/**
@@ -102,31 +100,14 @@ public void registerCacheProvider(@NonNull Class<? extends CacheProvider> cacheP
102100
}
103101
}
104102

105-
/**
106-
* @return the cache api settings singleton
107-
*/
108-
@NotNull
109-
public static CacheApiSettings getInstance() {
110-
if (INSTANCE == null) {
111-
synchronized (CacheApiSettings.class) {
112-
if (INSTANCE == null) {
113-
CacheApiSettings cacheApiSettings = new CacheApiSettings();
114-
populateProviders(cacheApiSettings);
115-
INSTANCE = cacheApiSettings;
116-
}
117-
}
118-
}
119-
return INSTANCE;
120-
}
121-
122-
private static void populateProviders(CacheApiSettings cacheApiSettings) {
103+
private void populateProviders() {
123104
log.debug("Xanthic: Registering canonical cache providers from the classpath...");
124105

125106
AtomicInteger registered = new AtomicInteger();
126107
Consumer<String> loadImpl = (providerClass) -> {
127108
try {
128109
Class<? extends CacheProvider> clazz = Class.forName(providerClass).asSubclass(CacheProvider.class);
129-
cacheApiSettings.registerCacheProvider(clazz, null); // lazy, init if needed
110+
registerCacheProvider(clazz, null); // lazy, init if needed
130111
registered.incrementAndGet();
131112
} catch (ClassNotFoundException cx) {
132113
log.trace("Xanthic: Could not find optional cache provider " + providerClass);
@@ -148,4 +129,16 @@ private static void populateProviders(CacheApiSettings cacheApiSettings) {
148129

149130
log.debug("Xanthic: Loaded {} canonical cache provider(s) on settings construction!", registered.get());
150131
}
132+
133+
/**
134+
* @return the cache api settings singleton
135+
*/
136+
@NotNull
137+
public static CacheApiSettings getInstance() {
138+
return SingletonHolder.INSTANCE;
139+
}
140+
141+
private static class SingletonHolder {
142+
private static final CacheApiSettings INSTANCE = new CacheApiSettings();
143+
}
151144
}

core/src/test/java/io/github/xanthic/cache/core/CacheRegistrationTest.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
import org.junit.jupiter.api.Test;
1313

1414
import java.lang.reflect.Field;
15+
import java.lang.reflect.Method;
1516
import java.time.Duration;
17+
import java.util.Map;
18+
import java.util.concurrent.atomic.AtomicReference;
1619

1720
import static org.junit.jupiter.api.Assertions.assertThrows;
1821

@@ -23,10 +26,19 @@ public class CacheRegistrationTest {
2326
@SneakyThrows
2427
void beforeEachTest() {
2528
// reset cache settings singleton
26-
Field instanceField = CacheApiSettings.class.getDeclaredField("INSTANCE");
27-
instanceField.setAccessible(true);
28-
instanceField.set(null, null);
29-
CacheApiSettings.getInstance();
29+
CacheApiSettings instance = CacheApiSettings.getInstance();
30+
31+
Field providers = CacheApiSettings.class.getDeclaredField("providers");
32+
providers.setAccessible(true);
33+
((Map<?, ?>) providers.get(instance)).clear();
34+
35+
Field defaultProvider = CacheApiSettings.class.getDeclaredField("defaultCacheProvider");
36+
defaultProvider.setAccessible(true);
37+
((AtomicReference<?>) defaultProvider.get(instance)).set(null);
38+
39+
Method populate = CacheApiSettings.class.getDeclaredMethod("populateProviders");
40+
populate.setAccessible(true);
41+
populate.invoke(instance);
3042
}
3143

3244
@Test

0 commit comments

Comments
 (0)