/**
* <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.Map;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.BasicEMap;
/**
* This class is an extension of BasicEMap which provides support for user-defined
* equality functions. Note that it thus breaks the contract of java.util.Map, as does
* BasicEMap when useEqualsForKey() returns false.
* The default behavior (no equality function specified) is equality by object reference.
* Methods containsValue(Object) and equals(Object) are always based on equality by
* object reference.
* The "F" prefix stands for "Flexible".
* @author Olivier Constant
*/
public class FHashMap<K, V> extends BasicEMap<K,V>
implements IEqualityBasedStructure {
/** The serial version ID */
private static final long serialVersionUID = 1L;
/** The non-null equality function */
private final IEqualityTester _equalityTester;
/**
* Constructor with default equality tester
*/
public FHashMap() {
this(null);
}
/**
* Constructor
* @param tester_p an equality tester (null stands for default)
*/
public FHashMap(IEqualityTester tester_p) {
super();
_equalityTester = (tester_p != null)? tester_p: DEFAULT_TESTER;
}
/**
* Constructor
* @param initialCapacity_p a positive initial capacity
* @param tester_p an equality tester (null stands for default)
*/
public FHashMap(int initialCapacity_p, IEqualityTester tester_p) {
super(initialCapacity_p);
_equalityTester = (tester_p != null)? tester_p: DEFAULT_TESTER;
}
/**
* Constructor
* @param map_p the non-null initial contents
* @param tester_p an equality tester (null stands for default)
*/
public FHashMap(Map<? extends K, ? extends V> map_p, IEqualityTester tester_p) {
super(2 * map_p.size()); // Cannot invoke similar super constructor
_equalityTester = (tester_p != null)? tester_p: DEFAULT_TESTER;
putAll(map_p);
}
/**
* @see org.eclipse.emf.common.util.BasicEMap#entryForKey(int, int, Object)
*/
@Override
protected Entry<K, V> entryForKey(int index_p, int hash_p, Object key_p) {
BasicEList<Entry<K, V>> eList = entryData[index_p];
if (eList != null) {
for (int j = 0; j < eList.size(); ++j) {
Entry<K, V> entry = eList.basicGet(j);
if (entry.getHash() == hash_p &&
getEqualityTester().areEqual(key_p, entry.getKey()))
return entry;
}
}
return null;
}
/**
* @see org.eclipse.emf.common.util.BasicEMap#entryIndexForKey(int, int, Object)
*/
@Override
protected int entryIndexForKey(int index_p, int hash_p, Object key_p) {
BasicEList<Entry<K, V>> eList = entryData[index_p];
if (eList != null) {
for (int j = 0; j < eList.size(); ++j) {
Entry<K, V> entry = eList.basicGet(j);
if (entry.getHash() == hash_p &&
getEqualityTester().areEqual(key_p, entry.getKey()))
return j;
}
}
return -1;
}
/**
* @see org.eclipse.emf.diffmerge.util.structures.IEqualityBasedStructure#getEqualityTester()
*/
public IEqualityTester getEqualityTester() {
return _equalityTester;
}
/**
* @see org.eclipse.emf.common.util.BasicEMap#hashOf(Object)
*/
@Override
protected int hashOf(Object key_p) {
return key_p == null ? 0 : getEqualityTester().hashCodeFor(key_p);
}
/**
* @see org.eclipse.emf.common.util.BasicEMap#indexOfKey(Object)
*/
@Override
public int indexOfKey(Object key_p) {
size = delegateEList.size();
for (int i = 0; i < size; ++i) {
Entry<K, V> entry = delegateEList.get(i);
if (getEqualityTester().areEqual(key_p, entry.getKey()))
return i;
}
return -1;
}
/**
* @see org.eclipse.emf.common.util.BasicEMap#useEqualsForKey()
*/
@Override
protected final boolean useEqualsForKey() {
return false;
}
/**
* @see org.eclipse.emf.common.util.BasicEMap#useEqualsForValue()
*/
@Override
protected final boolean useEqualsForValue() {
return false;
}
}