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

com.firefly.utils.collection.AbstractConcurrentAutomaticClearMap Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
package com.firefly.utils.collection;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

abstract public class AbstractConcurrentAutomaticClearMap implements ConcurrentAutomaticClearMap, ConcurrentMap {

	protected Map> map = new ConcurrentHashMap<>();
	protected ReferenceQueue refQueue = new ReferenceQueue<>();

	public void clearAllInvalidEntry() {
		Reference ref;
		while ((ref = refQueue.poll()) != null) {
			clearInvalidEntry(ref);
		}
	}

	abstract protected void clearInvalidEntry(Reference ref);

	abstract protected Reference createRefence(K key, V value);

	@Override
	public int size() {
		clearAllInvalidEntry();
		return map.size();
	}

	@Override
	public boolean isEmpty() {
		clearAllInvalidEntry();
		return map.isEmpty();
	}

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

	@Override
	public V get(Object key) {
		Reference ref = map.get(key);
		if (ref == null)
			return null;

		V value = ref.get();
		if (value == null) {
			clearInvalidEntry(ref);
			return null;
		} else {
			return value;
		}
	}

	@Override
	public V put(K key, V value) {
		clearAllInvalidEntry();
		Reference ref = map.put(key, createRefence(key, value));
		return ref != null ? ref.get() : null;
	}

	@Override
	public V putIfAbsent(K key, V value) {
		clearAllInvalidEntry();
		Reference ref = map.putIfAbsent(key, createRefence(key, value));
		return ref != null ? ref.get() : null;
	}

	@Override
	public void putAll(Map m) {
		clearAllInvalidEntry();
		for (Map.Entry entry : m.entrySet()) {
			put(entry.getKey(), entry.getValue());
		}
	}

	@Override
	public V replace(K key, V value) {
		Reference ref = map.replace(key, createRefence(key, value));
		return ref != null ? ref.get() : null;
	}

	@Override
	public boolean replace(K key, V oldValue, V newValue) {
		return map.replace(key, createRefence(key, oldValue), createRefence(key, newValue));
	}

	@Override
	public V remove(Object key) {
		clearAllInvalidEntry();
		Reference ref = map.remove(key);
		return ref != null ? ref.get() : null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean remove(Object key, Object value) {
		clearAllInvalidEntry();
		return map.remove(key, createRefence((K) key, (V) value));
	}

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

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

	@Override
	public Collection values() {
		Collection collection = new LinkedList<>();
		for (Map.Entry entry : entrySet()) {
			collection.add(entry.getValue());
		}
		return collection;
	}

	@Override
	public boolean containsValue(Object value) {
		for (V v : values()) {
			if (v != null && v.equals(value)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public Set> entrySet() {
		Set> set = new HashSet<>();
		for (Map.Entry> entry : map.entrySet()) {
			Reference ref = entry.getValue();
			V value = ref.get();
			if (value == null) {
				clearInvalidEntry(ref);
			} else {
				set.add(new MapEntryImpl(entry.getKey(), value));
			}
		}
		return set;
	}

	protected class MapEntryImpl implements Map.Entry {

		K key;
		V value;

		public MapEntryImpl(K key, V value) {
			this.key = key;
			this.value = value;
		}

		@Override
		public K getKey() {
			return key;
		}

		@Override
		public V getValue() {
			return value;
		}

		@Override
		public V setValue(V value) {
			this.value = value;
			return value;
		}

		@Override
		public String toString() {
			return "MapEntry [key=" + key + ", value=" + value + "]";
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy