Skip to content

Commit

Permalink
Optimize CacheKey handling for immutable sources
Browse files Browse the repository at this point in the history
Update `SpringIterableConfigurationPropertySource` so that cache keys
do not need to be checked if property sources are immutable.

See gh-16717
  • Loading branch information
dreis2211 authored and philwebb committed Jun 4, 2019
1 parent 071410c commit 44d8321
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Set;
import java.util.stream.Stream;

import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
Expand Down Expand Up @@ -192,21 +193,37 @@ private static final class CacheKey {

private final Object key;

private CacheKey(Object key) {
private final int size;

private final boolean unmodifiableKey;

private CacheKey(Object key, boolean unmodifiableKey) {
this.key = key;
this.size = calculateSize(key);
this.unmodifiableKey = unmodifiableKey;
}

public CacheKey copy() {
return new CacheKey(copyKey(this.key));
return new CacheKey(copyKey(this.key), this.unmodifiableKey);
}

private Object copyKey(Object key) {
if (this.unmodifiableKey) {
return key;
}
if (key instanceof Set) {
return new HashSet<Object>((Set<?>) key);
}
return ((String[]) key).clone();
}

private int calculateSize(Object key) {
if (key instanceof Set) {
return ((Set<?>) key).size();
}
return ((String[]) key).length;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
Expand All @@ -215,7 +232,11 @@ public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
return ObjectUtils.nullSafeEquals(this.key, ((CacheKey) obj).key);
CacheKey otherCacheKey = (CacheKey) obj;
if (this.size != otherCacheKey.size) {
return false;
}
return ObjectUtils.nullSafeEquals(this.key, otherCacheKey.key);
}

@Override
Expand All @@ -225,9 +246,10 @@ public int hashCode() {

public static CacheKey get(EnumerablePropertySource<?> source) {
if (source instanceof MapPropertySource) {
return new CacheKey(((MapPropertySource) source).getSource().keySet());
return new CacheKey(((MapPropertySource) source).getSource().keySet(),
source instanceof OriginTrackedMapPropertySource);
}
return new CacheKey(source.getPropertyNames());
return new CacheKey(source.getPropertyNames(), false);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import org.junit.Test;

import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.OriginLookup;
import org.springframework.core.env.EnumerablePropertySource;
Expand Down Expand Up @@ -160,7 +161,7 @@ public void containsDescendantOfShouldCheckSourceNames() {
}

@Test
public void propertySourceKeyDataChangeInvalidatesCache() {
public void simpleMapPropertySourceKeyDataChangeInvalidatesCache() {
// gh-13344
Map<String, Object> map = new LinkedHashMap<>();
map.put("key1", "value1");
Expand All @@ -184,6 +185,18 @@ public void concurrentModificationExceptionInvalidatesCache() {
source, DefaultPropertyMapper.INSTANCE);
assertThat(adapter.stream().count()).isEqualTo(2);
map.setThrowException(true);
}

public void originTrackedMapPropertySourceKeyAdditionInvalidatesCache() {
// gh-13344
Map<String, Object> map = new LinkedHashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
EnumerablePropertySource<?> source = new OriginTrackedMapPropertySource("test",
map);
SpringIterableConfigurationPropertySource adapter = new SpringIterableConfigurationPropertySource(
source, DefaultPropertyMapper.INSTANCE);
assertThat(adapter.stream().count()).isEqualTo(2);
map.put("key3", "value3");
assertThat(adapter.stream().count()).isEqualTo(3);
}
Expand Down

0 comments on commit 44d8321

Please sign in to comment.