patternjavaMinor
ConcurrentDecayingHashMap<K,V>, a concurrent decaying HashMap
Viewed 0 times
concurrenthashmapdecayingconcurrentdecayinghashmap
Problem
I wrote a wrapper for Java's
I'd be thankful for a review! A basic fully functional test is attached.
```
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentDecayingHashMap implements AutoCloseable {
private final ConcurrentHashMap map = new ConcurrentHashMap<>();
private final Thread cleanerThread;
public ConcurrentDecayingHashMap() {
this(1000); // 1 second
}
public ConcurrentDecayingHashMap(int cleanupIntervalInMilis) {
if (cleanupIntervalInMilis {
try {
Collection valueWrappers = map.values();
Thread currentThread = Thread.currentThread();
while (!currentThread.isInterrupted()) {
long currentTime = System.currentTimeMillis();
for (ValueWrapper valueWrapper : valueWrappers) {
// outer check to avoid excessive amount of map.compute calls
if (currentTime >= valueWrapper.timeOfDeath && valueWrapper.timeOfDeath > 0) {
map.compute(valueWrapper.key, (k, oldValueWrapper) -> {
// inner check because value could have changed after outer check
if (currentTime >= oldValueWrapper.timeOfDeath && oldValueWrapper.timeOfDeath > 0) {
return null; // removes the value from the map
}
return oldValueWrapper; // no change
});
}
}
ConcurrentHashMap that enables you to add a decay time to inserted values, meaning they will be automatically removed after the given time. This functionality is implemented by a cleaning thread that runs until .close() is called. I deliberately did not extend the ConcurrentHashMap because I simply wanted to implement the core functionality. I'd be thankful for a review! A basic fully functional test is attached.
```
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentDecayingHashMap implements AutoCloseable {
private final ConcurrentHashMap map = new ConcurrentHashMap<>();
private final Thread cleanerThread;
public ConcurrentDecayingHashMap() {
this(1000); // 1 second
}
public ConcurrentDecayingHashMap(int cleanupIntervalInMilis) {
if (cleanupIntervalInMilis {
try {
Collection valueWrappers = map.values();
Thread currentThread = Thread.currentThread();
while (!currentThread.isInterrupted()) {
long currentTime = System.currentTimeMillis();
for (ValueWrapper valueWrapper : valueWrappers) {
// outer check to avoid excessive amount of map.compute calls
if (currentTime >= valueWrapper.timeOfDeath && valueWrapper.timeOfDeath > 0) {
map.compute(valueWrapper.key, (k, oldValueWrapper) -> {
// inner check because value could have changed after outer check
if (currentTime >= oldValueWrapper.timeOfDeath && oldValueWrapper.timeOfDeath > 0) {
return null; // removes the value from the map
}
return oldValueWrapper; // no change
});
}
}
Solution
For the cleanup thread it sounds like a more optimal way of looking for
out of date values would be a priority queue sorted by next eviction
timestamp; that way only a few rather than all of the entries would need
to be checked. Similarly, the timeout could be adjusted based on what
the next expected time for eviction would be. If there are no entries
in the map the thread could also be stopped entirely.
In
message immediately handles the
behaviour could be clarified in the description IMO.
Apart from the demo there should also be actual unit tests to test that
all the assumptions hold in a variety of circumstances.
out of date values would be a priority queue sorted by next eviction
timestamp; that way only a few rather than all of the entries would need
to be checked. Similarly, the timeout could be adjusted based on what
the next expected time for eviction would be. If there are no entries
in the map the thread could also be stopped entirely.
In
put the description says that the value can't be null - but themessage immediately handles the
null case by calling remove. Thatbehaviour could be clarified in the description IMO.
Apart from the demo there should also be actual unit tests to test that
all the assumptions hold in a variety of circumstances.
Context
StackExchange Code Review Q#110440, answer score: 3
Revisions (0)
No revisions yet.