kodisha
kodisha

Reputation: 894

Is there concurrent & self-expiring & ordered hash map in java

I'm using ConcurrentHashMap from google guava (via MapMaker), but that implementation isn't ordered. There is ConcurrentSkipListMap in google guava, but that structure can't expire.

Is there any structure that can do both?

Upvotes: 4

Views: 3903

Answers (6)

Ray
Ray

Reputation: 4869

It sounds like you want an ordered view of the concurrent expiring map. You could build one from ForwardingMap

Upvotes: 0

user207421
user207421

Reputation: 310980

Extend java.util.LinkedHashMap and override removeEldestEntry() to do whatever you want it to do.

Upvotes: 1

donaldh
donaldh

Reputation: 833

Why not just use two ordered maps? One is keyed by timestamp and is used to find expired events. The other is keyed by UUID and is used to find events. When removing expired events, use the UUID of the event to remove from the second map.

Upvotes: 0

Enno Shioji
Enno Shioji

Reputation: 26882

I'd use ConcurrentSkipListMap and iterate the map periodically to purge expired stuff. Since the skiplist is unbounded this opens up a possibility of a memoryleak, when the eviction thread cannot catch up, but in practice this seems very, very unlikely unless you do something extreme.I've also done something like this when I didn't want to use a background thread:

static AtomicInteger cnt = new AtomicInteger();

Val put(K key, V val){
    //Do the usual stuff
    if(cnt.getAndIncrement() % 100 == 0){
        //iterate map and evict stuff
    }
}

The if(cnt.getAndIncrement() % 100 == 0) may have been a "clever optimization", so perhaps you could just iterate and evict everytime like matt b suggests.

Oh just one caveat when you do this.... Be sure to break equality between different entities when the timestamps coincide:

class Entity implaments Comparable<Entity>{
    static AtomicInteger SEQ = new AtomicInteger();
    int id = SEQ.getAndIncrement();
    long timeStamp = System.currentTimeMillis();

    int compareTo(Entity other){
        // compare by timestamp
        // If timestamps are equal, don't just return 0 yet!!
        // Compare by id and return 0 ONLY IF the id equals.
        // Otherwise entities disappear from your ordered map and 
        // it's really annoying to debug.
}

Upvotes: 2

matt b
matt b

Reputation: 139971

If you have an ordered Map (I'm assuming the ordering is based on timestamp), then whenever you add or get items from the Map, you can simply scan from the least ordered value in the Map to the current timestamp - 60 seconds and remove any that fall short. The ordered property of the Map means you don't need to scan the full list on every operation.

Upvotes: 0

Arafangion
Arafangion

Reputation: 11940

Sounds like you have very specific and unusual requirements. You'll probably have to write it yourself.

Upvotes: 0

Related Questions