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

org.eclipse.osgi.internal.serviceregistry.ShrinkableValueCollectionMap Maven / Gradle / Ivy

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2010, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.internal.serviceregistry;

import java.util.*;

public class ShrinkableValueCollectionMap extends AbstractMap> implements Map> {
	final Map>> map;
	Map> values;

	public ShrinkableValueCollectionMap(Map>> m) {
		if (m == null) {
			throw new NullPointerException();
		}
		map = m;
		values = null;
	}

	@Override
	public void clear() {
		map.clear();
		if (values != null) {
			values.clear();
		}
	}

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

	@Override
	public boolean containsValue(Object value) {
		/* Since values are collections and the collection has identity equality,
		 * there is no way any value could be contained in this map unless that
		 * value has already been gotten from this map.
		 */
		if (values == null) {
			return false;
		}
		return values.containsValue(value);
	}

	@Override
	public Set>> entrySet() {
		return new EntrySet();
	}

	@Override
	public Collection get(Object key) {
		Collection value = null;
		if (values != null) {
			value = values.get(key);
		}
		if (value == null) {
			Set> entrySet = map.get(key);
			if (entrySet == null) {
				return null;
			}
			value = new ShrinkableEntrySetValueCollection<>(entrySet);
			if (values == null) {
				values = new HashMap<>(map.size());
			}
			values.put(key, value);
		}
		return value;
	}

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

	@Override
	public Collection remove(Object key) {
		Set> entrySet = map.remove(key);
		Collection value = null;
		if (values != null) {
			value = values.remove(key);
		}
		if ((value == null) && (entrySet != null)) {
			value = new ShrinkableEntrySetValueCollection<>(entrySet);
		}
		return value;
	}

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

	/**
	 * Set class used for entry sets.
	 */
	private final class EntrySet extends AbstractSet>> {
		EntrySet() {
			super();
		}

		@Override
		public Iterator>> iterator() {
			return new EntryIterator();
		}

		@Override
		public int size() {
			return ShrinkableValueCollectionMap.this.size();
		}
	}

	/**
	 * Iterator class used for entry sets.
	 */
	private final class EntryIterator implements Iterator>> {
		private final Iterator iter;
		private K last;

		EntryIterator() {
			iter = map.keySet().iterator();
		}

		@Override
		public boolean hasNext() {
			return iter.hasNext();
		}

		@Override
		public Map.Entry> next() {
			last = iter.next();
			return new Entry(last);
		}

		@Override
		public void remove() {
			iter.remove();
			if (values != null) {
				values.remove(last);
			}
		}
	}

	/**
	 * This class represents the entry in this map.
	 */
	private final class Entry implements Map.Entry> {
		private final K key;
		private Collection value;

		Entry(final K k) {
			key = k;
		}

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

		@Override
		public Collection getValue() {
			if (value == null) {
				value = ShrinkableValueCollectionMap.this.get(key);
			}
			return value;
		}

		@Override
		public Collection setValue(Collection value) {
			throw new UnsupportedOperationException(); // entries cannot be modified.
		}

		@Override
		public String toString() {
			return getKey() + "=" + getValue(); //$NON-NLS-1$
		}

		@Override
		public int hashCode() {
			return hash(getKey()) ^ hash(getValue());
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == this) {
				return true;
			}
			if (!(obj instanceof Map.Entry)) {
				return false;
			}
			Map.Entry other = (Map.Entry) obj;
			return equality(getKey(), other.getKey()) && equality(getValue(), other.getValue());
		}
	}

	static int hash(Object one) {
		return (one == null) ? 0 : one.hashCode();
	}

	static boolean equality(Object one, Object two) {
		return (one == null) ? (two == null) : one.equals(two);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy