All Downloads are FREE. Search and download functionalities are using the official Maven repository.

us.bpsm.edn.Interner Maven / Gradle / Ivy

// (c) 2012 B Smith-Mannschott -- Distributed under the Eclipse Public License
package us.bpsm.edn;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

class Interner {

    private final ConcurrentHashMap> table =
            new ConcurrentHashMap>();
    private final ReferenceQueue refQueue = new ReferenceQueue();

    public V intern(K key, V value) {
        while (true) {
            clearDeadEntries();
            WeakReference newRef = new WeakReference(value, refQueue);
            Reference existingRef = table.putIfAbsent(key, newRef);
            if (existingRef == null) {
                // newRef has been entered into the cache
                return value;
            }

            // existingRef was found in the cache; newRef is garbage
            V existingValue = existingRef.get();
            if (existingValue != null) {
                return existingValue;
            }

            // existingRef's referent has been collected out from under us
            table.remove(key, existingRef);
        }
    }

    private void clearDeadEntries() {
        if (refQueue.poll() == null) {
            // empty queue indicates that there's nothing to clear
            return;
        }
        while (refQueue.poll() != null) {
            // wait until there's nothing more in flight in the queue
        }
        for (Map.Entry> me: table.entrySet()) {
            Reference ref = me.getValue();
            if (ref != null && ref.get() == null) {
                table.remove(me.getKey(), ref);
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy