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

com.couchbase.lite.support.WeakValueHashMap Maven / Gradle / Ivy

package com.couchbase.lite.support;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

public class WeakValueHashMap extends AbstractMap {

    private HashMap> references;
    private ReferenceQueue referenceQueue;

    public WeakValueHashMap() {
        references = new HashMap>();
        referenceQueue = new ReferenceQueue();
    }

    public WeakValueHashMap(Map map) {
        this();
        for (Map.Entry entry : map.entrySet() ) {
            put(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public V put(K key, V value) {
        pruneDeadReferences();
        WeakValue valueRef = new WeakValue(key, value, referenceQueue);
        return getReferenceValue(references.put(key, valueRef));
    };

    @Override
    public V get(Object key) {
        pruneDeadReferences();
        return getReferenceValue(references.get(key));
    }

    @Override
    public V remove(Object key) {
        V value = getReferenceValue(references.get(key));
        references.remove(key);
        return value;
    }

    @Override
    public void clear() {
        references.clear();
    }

    @Override
    public boolean containsKey(Object key) {
        pruneDeadReferences();
        return references.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        pruneDeadReferences();
        for (Map.Entry> entry : references.entrySet()) {
            if (value == getReferenceValue(entry.getValue())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Set keySet() {
        pruneDeadReferences();
        return references.keySet();
    }

    @Override
    public int size() {
        pruneDeadReferences();
        return references.size();
    }

    @Override
    public Set> entrySet() {
        pruneDeadReferences();

        Set> entries = new LinkedHashSet>();
        for (Map.Entry> entry : references.entrySet()) {
            entries.add(new AbstractMap.SimpleEntry(entry.getKey(), getReferenceValue(entry.getValue())));
        }
        return entries;
    }

    public Collection values() {
        pruneDeadReferences();

        Collection values = new ArrayList();
        for (WeakValue valueRef : references.values()) {
            values.add(getReferenceValue(valueRef));
        }
        return values;
    }

    private V getReferenceValue(WeakValue valueRef) {
        return valueRef == null ? null : valueRef.get();
    }

    private void pruneDeadReferences() {
        WeakValue valueRef;
        while ( (valueRef = (WeakValue) referenceQueue.poll()) != null ) {
            references.remove(valueRef.getKey());
        }
    }

    private class WeakValue extends WeakReference {
        private final K key;

        private WeakValue(K key, T value, ReferenceQueue queue) {
            super(value, queue);
            this.key = key;
        }

        private K getKey() {
            return key;
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy