Make ConcurrentReferenceHashMap more JIT friendly
Update `ConcurrentReferenceHashMap` to make some methods more inline friendly, and to manually inline a few others. These minor optimizations don't make a great deal of difference for most applications, but seem worthwhile since we use `ConcurrentReferenceHashMap` for many internal caches. Closes gh-22566
This commit is contained in:
parent
aa4e56b251
commit
e3a86be122
|
|
@ -35,6 +35,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap.Reference;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap.Restructure;
|
||||
|
||||
/**
|
||||
* A {@link ConcurrentHashMap} that uses {@link ReferenceType#SOFT soft} or
|
||||
|
|
@ -232,27 +234,24 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
|
|||
@Override
|
||||
@Nullable
|
||||
public V get(@Nullable Object key) {
|
||||
Entry<K, V> entry = getEntryIfAvailable(key);
|
||||
Reference<K, V> ref = getReference(key, Restructure.WHEN_NECESSARY);
|
||||
Entry<K, V> entry = (ref != null ? ref.get() : null);
|
||||
return (entry != null ? entry.getValue() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public V getOrDefault(@Nullable Object key, @Nullable V defaultValue) {
|
||||
Entry<K, V> entry = getEntryIfAvailable(key);
|
||||
Reference<K, V> ref = getReference(key, Restructure.WHEN_NECESSARY);
|
||||
Entry<K, V> entry = (ref != null ? ref.get() : null);
|
||||
return (entry != null ? entry.getValue() : defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(@Nullable Object key) {
|
||||
Entry<K, V> entry = getEntryIfAvailable(key);
|
||||
return (entry != null && ObjectUtils.nullSafeEquals(entry.getKey(), key));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Entry<K, V> getEntryIfAvailable(@Nullable Object key) {
|
||||
Reference<K, V> ref = getReference(key, Restructure.WHEN_NECESSARY);
|
||||
return (ref != null ? ref.get() : null);
|
||||
Entry<K, V> entry = (ref != null ? ref.get() : null);
|
||||
return (entry != null && ObjectUtils.nullSafeEquals(entry.getKey(), key));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -573,9 +572,15 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
|
|||
*/
|
||||
protected final void restructureIfNecessary(boolean allowResize) {
|
||||
int currCount = this.count.get();
|
||||
boolean needsResize = (currCount > 0 && currCount >= this.resizeThreshold);
|
||||
boolean needsResize = allowResize && (currCount > 0 && currCount >= this.resizeThreshold);
|
||||
Reference<K, V> ref = this.referenceManager.pollForPurge();
|
||||
if (ref != null || (needsResize && allowResize)) {
|
||||
if (ref != null || (needsResize)) {
|
||||
restructure(allowResize, ref);
|
||||
}
|
||||
}
|
||||
|
||||
private void restructure(boolean allowResize, Reference<K, V> ref) {
|
||||
boolean needsResize;
|
||||
lock();
|
||||
try {
|
||||
int countAfterRestructure = this.count.get();
|
||||
|
|
@ -633,7 +638,6 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
|
|||
unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Reference<K, V> findInChain(Reference<K, V> ref, @Nullable Object key, int hash) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue