mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Polishing
This commit is contained in:
@@ -102,7 +102,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
if (this.capacity == 0) {
|
||||
return this.generator.apply(key);
|
||||
}
|
||||
final Node<K, V> node = this.cache.get(key);
|
||||
Node<K, V> node = this.cache.get(key);
|
||||
if (node == null) {
|
||||
V value = this.generator.apply(key);
|
||||
put(key, value);
|
||||
@@ -115,9 +115,9 @@ public final class ConcurrentLruCache<K, V> {
|
||||
private void put(K key, V value) {
|
||||
Assert.notNull(key, "key must not be null");
|
||||
Assert.notNull(value, "value must not be null");
|
||||
final CacheEntry<V> cacheEntry = new CacheEntry<>(value, CacheEntryState.ACTIVE);
|
||||
final Node<K, V> node = new Node<>(key, cacheEntry);
|
||||
final Node<K, V> prior = this.cache.putIfAbsent(node.key, node);
|
||||
CacheEntry<V> cacheEntry = new CacheEntry<>(value, CacheEntryState.ACTIVE);
|
||||
Node<K, V> node = new Node<>(key, cacheEntry);
|
||||
Node<K, V> prior = this.cache.putIfAbsent(node.key, node);
|
||||
if (prior == null) {
|
||||
processWrite(new AddTask(node));
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
|
||||
private void processRead(Node<K, V> node) {
|
||||
boolean drainRequested = this.readOperations.recordRead(node);
|
||||
final DrainStatus status = this.drainStatus.get();
|
||||
DrainStatus status = this.drainStatus.get();
|
||||
if (status.shouldDrainBuffers(drainRequested)) {
|
||||
drainOperations();
|
||||
}
|
||||
@@ -228,7 +228,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
* {@code false} if there was no matching key
|
||||
*/
|
||||
public boolean remove(K key) {
|
||||
final Node<K, V> node = this.cache.remove(key);
|
||||
Node<K, V> node = this.cache.remove(key);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -237,27 +237,29 @@ public final class ConcurrentLruCache<K, V> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Transition the node from the {@code active} state to the {@code pending removal} state,
|
||||
* if the transition is valid.
|
||||
*/
|
||||
private void markForRemoval(Node<K, V> node) {
|
||||
for (; ; ) {
|
||||
final CacheEntry<V> current = node.get();
|
||||
while (true) {
|
||||
CacheEntry<V> current = node.get();
|
||||
if (!current.isActive()) {
|
||||
return;
|
||||
}
|
||||
final CacheEntry<V> pendingRemoval = new CacheEntry<>(current.value, CacheEntryState.PENDING_REMOVAL);
|
||||
CacheEntry<V> pendingRemoval = new CacheEntry<>(current.value, CacheEntryState.PENDING_REMOVAL);
|
||||
if (node.compareAndSet(current, pendingRemoval)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write operation recorded when a new entry is added to the cache.
|
||||
*/
|
||||
private final class AddTask implements Runnable {
|
||||
|
||||
final Node<K, V> node;
|
||||
|
||||
AddTask(Node<K, V> node) {
|
||||
@@ -275,7 +277,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
|
||||
private void evictEntries() {
|
||||
while (currentSize.get() > capacity) {
|
||||
final Node<K, V> node = evictionQueue.poll();
|
||||
Node<K, V> node = evictionQueue.poll();
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
@@ -283,7 +285,6 @@ public final class ConcurrentLruCache<K, V> {
|
||||
markAsRemoved(node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -291,6 +292,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
* Write operation recorded when an entry is removed to the cache.
|
||||
*/
|
||||
private final class RemovalTask implements Runnable {
|
||||
|
||||
final Node<K, V> node;
|
||||
|
||||
RemovalTask(Node<K, V> node) {
|
||||
@@ -310,7 +312,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
*/
|
||||
private enum DrainStatus {
|
||||
|
||||
/*
|
||||
/**
|
||||
* No drain operation currently running.
|
||||
*/
|
||||
IDLE {
|
||||
@@ -320,7 +322,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
/**
|
||||
* A drain operation is required due to a pending write modification.
|
||||
*/
|
||||
REQUIRED {
|
||||
@@ -330,7 +332,7 @@ public final class ConcurrentLruCache<K, V> {
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
/**
|
||||
* A drain operation is in progress.
|
||||
*/
|
||||
PROCESSING {
|
||||
@@ -367,12 +369,6 @@ public final class ConcurrentLruCache<K, V> {
|
||||
|
||||
private static final int BUFFER_COUNT = detectNumberOfBuffers();
|
||||
|
||||
private static int detectNumberOfBuffers() {
|
||||
int availableProcessors = Runtime.getRuntime().availableProcessors();
|
||||
int nextPowerOfTwo = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(availableProcessors - 1));
|
||||
return Math.min(4, nextPowerOfTwo);
|
||||
}
|
||||
|
||||
private static final int BUFFERS_MASK = BUFFER_COUNT - 1;
|
||||
|
||||
private static final int MAX_PENDING_OPERATIONS = 32;
|
||||
@@ -383,19 +379,13 @@ public final class ConcurrentLruCache<K, V> {
|
||||
|
||||
private static final int BUFFER_INDEX_MASK = BUFFER_SIZE - 1;
|
||||
|
||||
/*
|
||||
* Number of operations recorded, for each buffer
|
||||
*/
|
||||
// Number of operations recorded, for each buffer
|
||||
private final AtomicLongArray recordedCount = new AtomicLongArray(BUFFER_COUNT);
|
||||
|
||||
/*
|
||||
* Number of operations read, for each buffer
|
||||
*/
|
||||
// Number of operations read, for each buffer
|
||||
private final long[] readCount = new long[BUFFER_COUNT];
|
||||
|
||||
/*
|
||||
* Number of operations processed, for each buffer
|
||||
*/
|
||||
// Number of operations processed, for each buffer
|
||||
private final AtomicLongArray processedCount = new AtomicLongArray(BUFFER_COUNT);
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@@ -403,10 +393,11 @@ public final class ConcurrentLruCache<K, V> {
|
||||
|
||||
private final EvictionQueue<K, V> evictionQueue;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
ReadOperations(EvictionQueue<K, V> evictionQueue) {
|
||||
this.evictionQueue = evictionQueue;
|
||||
for (int i = 0; i < BUFFER_COUNT; i++) {
|
||||
this.buffers[i] = new AtomicReferenceArray<>(BUFFER_SIZE);
|
||||
this.buffers[i] = new AtomicReferenceArray(BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,6 +449,12 @@ public final class ConcurrentLruCache<K, V> {
|
||||
}
|
||||
this.processedCount.lazySet(bufferIndex, writeCount);
|
||||
}
|
||||
|
||||
private static int detectNumberOfBuffers() {
|
||||
int availableProcessors = Runtime.getRuntime().availableProcessors();
|
||||
int nextPowerOfTwo = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(availableProcessors - 1));
|
||||
return Math.min(4, nextPowerOfTwo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -536,10 +533,9 @@ public final class ConcurrentLruCache<K, V> {
|
||||
if (this.first == null) {
|
||||
return null;
|
||||
}
|
||||
final Node<K, V> f = this.first;
|
||||
final Node<K, V> next = f.getNext();
|
||||
Node<K, V> f = this.first;
|
||||
Node<K, V> next = f.getNext();
|
||||
f.setNext(null);
|
||||
|
||||
this.first = next;
|
||||
if (next == null) {
|
||||
this.last = null;
|
||||
@@ -558,13 +554,12 @@ public final class ConcurrentLruCache<K, V> {
|
||||
}
|
||||
|
||||
private boolean contains(Node<K, V> e) {
|
||||
return (e.getPrevious() != null) || (e.getNext() != null) || (e == this.first);
|
||||
return (e.getPrevious() != null || e.getNext() != null || e == this.first);
|
||||
}
|
||||
|
||||
private void linkLast(final Node<K, V> e) {
|
||||
final Node<K, V> l = this.last;
|
||||
private void linkLast(Node<K, V> e) {
|
||||
Node<K, V> l = this.last;
|
||||
this.last = e;
|
||||
|
||||
if (l == null) {
|
||||
this.first = e;
|
||||
}
|
||||
@@ -575,8 +570,8 @@ public final class ConcurrentLruCache<K, V> {
|
||||
}
|
||||
|
||||
private void unlink(Node<K, V> e) {
|
||||
final Node<K, V> prev = e.getPrevious();
|
||||
final Node<K, V> next = e.getNext();
|
||||
Node<K, V> prev = e.getPrevious();
|
||||
Node<K, V> next = e.getNext();
|
||||
if (prev == null) {
|
||||
this.first = next;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user