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

org.h2.util.SoftHashMap Maven / Gradle / Ivy

There is a newer version: 1.0.0-beta2
Show newest version
/*
 * Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
 * and the EPL 1.0 (https://h2database.com/html/license.html).
 * Initial Developer: H2 Group
 */
package org.h2.util;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Map which stores items using SoftReference. Items can be garbage collected
 * and removed. It is not a general purpose cache, as it doesn't implement some
 * methods, and others not according to the map definition, to improve speed.
 *
 * @param  the key type
 * @param  the value type
 */
public class SoftHashMap extends AbstractMap {

    private final Map> map;
    private final ReferenceQueue queue = new ReferenceQueue<>();

    public SoftHashMap() {
        map = new HashMap<>();
    }

    @SuppressWarnings("unchecked")
    private void processQueue() {
        while (true) {
            Reference o = queue.poll();
            if (o == null) {
                return;
            }
            SoftValue k = (SoftValue) o;
            Object key = k.key;
            map.remove(key);
        }
    }

    @Override
    public V get(Object key) {
        processQueue();
        SoftReference o = map.get(key);
        if (o == null) {
            return null;
        }
        return o.get();
    }

    /**
     * Store the object. The return value of this method is null or a
     * SoftReference.
     *
     * @param key the key
     * @param value the value
     * @return null or the old object.
     */
    @Override
    public V put(K key, V value) {
        processQueue();
        SoftValue old = map.put(key, new SoftValue<>(value, queue, key));
        return old == null ? null : old.get();
    }

    /**
     * Remove an object.
     *
     * @param key the key
     * @return null or the old object
     */
    @Override
    public V remove(Object key) {
        processQueue();
        SoftReference ref = map.remove(key);
        return ref == null ? null : ref.get();
    }

    @Override
    public void clear() {
        processQueue();
        map.clear();
    }

    @Override
    public Set> entrySet() {
        throw new UnsupportedOperationException();
    }

    /**
     * A soft reference that has a hard reference to the key.
     */
    private static class SoftValue extends SoftReference {
        final Object key;

        public SoftValue(T ref, ReferenceQueue q, Object key) {
            super(ref, q);
            this.key = key;
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy