/**
* <copyright>
*
* Copyright (c) 2010-2016 Thales Global Services S.A.S.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Thales Global Services S.A.S. - initial API and implementation
*
* </copyright>
*/
package org.eclipse.emf.diffmerge.util.structures;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* A simple implementation of a modifiable finitary binary relation based on
* a HashMap of ArrayLists conforming to the IEqualityTester.
* The default equality tester is by reference.
* @param <T> the type of the domain elements
* @param <U> the type of the codomain elements
* @author Olivier Constant
*/
public class HashBinaryRelation<T, U> extends AbstractBinaryRelation<T, U>
implements IRangedBinaryRelation.Editable<T, U> {
/** The non-null internal encoding of the relation */
protected final FHashMap<T, List<U>> _contents;
/**
* Constructor
* @param tester_p a potentially null equality tester for comparing elements
*/
public HashBinaryRelation(IEqualityTester tester_p) {
super(tester_p);
_contents = new FHashMap<T, List<U>>(getEqualityTester());
}
/**
* Constructor
*/
public HashBinaryRelation() {
this(null);
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IBinaryRelation.Editable#add(java.lang.Object, java.lang.Object)
*/
public boolean add(T source_p, U target_p) {
assert source_p != null && target_p != null;
boolean result = false;
List<U> values = _contents.get(source_p);
if (values == null) {
values = new FArrayList<U>(getEqualityTester());
_contents.put(source_p, values);
}
if (!values.contains(target_p))
result = values.add(target_p);
return result;
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IBinaryRelation.Editable#clear()
*/
public void clear() {
_contents.clear();
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IBinaryRelation#get(Object)
*/
public List<U> get(T element_p) {
assert element_p != null;
List<U> result;
List<U> values = _contents.get(element_p);
if (values == null)
result = Collections.emptyList();
else
result = Collections.unmodifiableList(values);
return result;
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IRangedBinaryRelation#isEmpty()
*/
public boolean isEmpty() {
return _contents.isEmpty();
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IBinaryRelation.Editable#remove(java.lang.Object, java.lang.Object)
*/
public boolean remove(T source_p, U target_p) {
assert source_p != null && target_p != null;
boolean result = false;
List<U> values = _contents.get(source_p);
if (values != null) {
result = values.remove(target_p);
if (values.isEmpty())
_contents.removeKey(source_p);
}
return result;
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IRangedBinaryRelation#getSources()
*/
public Collection<T> getSources() {
return Collections.unmodifiableSet(_contents.keySet());
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IRangedBinaryRelation#getTargets()
*/
public Collection<U> getTargets() {
Set<U> result = new FHashSet<U>(getEqualityTester());
for (List<U> valueList : _contents.values()) {
result.addAll(valueList);
}
return Collections.unmodifiableSet(result);
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IRangedBinaryRelation.Editable#removeSource(java.lang.Object)
*/
public boolean removeSource(T source_p) {
assert source_p != null;
List<U> values = _contents.removeKey(source_p);
boolean result = values != null;
return result;
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IRangedBinaryRelation.Editable#removeTarget(java.lang.Object)
*/
public boolean removeTarget(U target_p) {
boolean result = false;
Collection<T> sources = new FArrayList<T>(getSources(), getEqualityTester());
for (T source : sources) {
result = result || remove(source, target_p);
}
return result;
}
}