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

com.jidesoft.swing.SoftHashMap Maven / Gradle / Ivy

There is a newer version: 3.6.18
Show newest version
/*
 * @(#)SoftHashMap.java 9/9/2009
 *
 * Copyright 2002 - 2009 JIDE Software Inc. All rights reserved.
 */

package com.jidesoft.swing;

import java.io.Serializable;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.*;

/**
 * This implementation is taken from The Java
 * Specialists' Newsletter [Issue 098] with permission of the original author.
 *
 * @author Dr. Heinz M. Kabutz
 */
class SoftHashMap extends AbstractMap implements Serializable {
    private static final long serialVersionUID = 2456984612468446907L;

    /**
     * The internal HashMap that will hold the SoftReference.
     */
    private final Map> hash = new HashMap>();

    private final Map, K> reverseLookup = new HashMap, K>();

    /**
     * Reference queue for cleared SoftReference objects.
     */
    private final ReferenceQueue queue = new ReferenceQueue();

    @Override
    public V get(Object key) {
        expungeStaleEntries();
        V result = null;
        // We get the SoftReference represented by that key
        SoftReference soft_ref = hash.get(key);
        if (soft_ref != null) {
            // From the SoftReference we get the value, which can be
            // null if it has been garbage collected
            result = soft_ref.get();
            if (result == null) {
                // If the value has been garbage collected, remove the
                // entry from the HashMap.
                hash.remove(key);
                reverseLookup.remove(soft_ref);
            }
        }
        return result;
    }

    private void expungeStaleEntries() {
        Reference sv;
        while ((sv = queue.poll()) != null) {
            hash.remove(reverseLookup.remove(sv));
        }
    }

    @Override
    public V put(K key, V value) {
        expungeStaleEntries();
        SoftReference soft_ref = new SoftReference(value, queue);
        reverseLookup.put(soft_ref, key);
        SoftReference result = hash.put(key, soft_ref);
        if (result == null)
            return null;
        return result.get();
    }

    @Override
    public V remove(Object key) {
        expungeStaleEntries();
        SoftReference result = hash.remove(key);
        if (result == null)
            return null;
        return result.get();
    }

    @Override
    public void clear() {
        hash.clear();
        reverseLookup.clear();
    }

    @Override
    public int size() {
        expungeStaleEntries();
        return hash.size();
    }

    /**
     * Returns a copy of the key/values in the map at the point of calling. However, setValue still sets the value in
     * the actual SoftHashMap.
     */
    @Override
    public Set> entrySet() {
        expungeStaleEntries();
        Set> result = new LinkedHashSet>();
        for (final Entry> entry : hash.entrySet()) {
            final V value = entry.getValue().get();
            if (value != null) {
                result.add(new Entry() {
                    public K getKey() {
                        return entry.getKey();
                    }

                    public V getValue() {
                        return value;
                    }

                    public V setValue(V v) {
                        entry.setValue(new SoftReference(v, queue));
                        return value;
                    }
                });
            }
        }
        return result;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy