common-utils/src/main/java/org/warp/commonutils/type/HashBiAssociation.java

143 lines
3.1 KiB
Java

package org.warp.commonutils.type;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Objects;
import java.util.Optional;
public class HashBiAssociation<T, U> implements BiAssociation<T, U> {
private final Object2ObjectOpenHashMap<T, U> associations;
private final Object2ObjectOpenHashMap<U, T> inverseAssociations;
public HashBiAssociation() {
this.associations = new Object2ObjectOpenHashMap<>();
this.inverseAssociations = new Object2ObjectOpenHashMap<>();
}
private HashBiAssociation(Object2ObjectOpenHashMap<T, U> associations,
Object2ObjectOpenHashMap<U, T> inverseAssociations) {
this.associations = associations;
this.inverseAssociations = inverseAssociations;
}
@Override
public Optional<U> link(T src, U dest) {
Objects.requireNonNull(src);
Objects.requireNonNull(dest);
var previousSrc = inverseAssociations.put(dest, src);
// Return immediately if the link already exists
if (Objects.equals(src, previousSrc)) {
return Optional.of(dest);
}
// Remove the previous association
if (previousSrc != null) {
associations.remove(previousSrc);
}
var previousDest = associations.put(src, dest);
// Remove the previous association
if (previousDest != null) {
inverseAssociations.remove(previousDest);
}
return Optional.ofNullable(previousDest);
}
@Override
public boolean unlink(T src, U dest) {
Objects.requireNonNull(src);
Objects.requireNonNull(dest);
if (!Objects.equals(dest, associations.get(src))) {
return false;
}
associations.remove(src);
inverseAssociations.remove(dest);
return true;
}
@Override
public Optional<U> unlink(T src) {
Objects.requireNonNull(src);
var dest = associations.remove(src);
if (dest != null) {
inverseAssociations.remove(dest);
}
return Optional.ofNullable(dest);
}
@Override
public Optional<T> unlinkFromSource(U dest) {
Objects.requireNonNull(dest);
var src = inverseAssociations.remove(dest);
if (src != null) {
associations.remove(src);
}
return Optional.ofNullable(src);
}
@Override
public boolean hasLink(T src) {
Objects.requireNonNull(src);
return associations.containsKey(src);
}
@Override
public boolean hasLinkSource(U dest) {
Objects.requireNonNull(dest);
return inverseAssociations.containsKey(dest);
}
@Override
public boolean hasLink(T src, U dest) {
Objects.requireNonNull(src);
Objects.requireNonNull(dest);
return Objects.equals(dest, associations.get(src));
}
@Override
public Optional<U> getLink(T src) {
Objects.requireNonNull(src);
return Optional.ofNullable(associations.get(src));
}
@Override
public Optional<T> getLinkSource(U dest) {
Objects.requireNonNull(dest);
return Optional.ofNullable(inverseAssociations.get(dest));
}
@Override
public void clear() {
associations.clear();
inverseAssociations.clear();
}
@Override
public int size() {
return inverseAssociations.size();
}
@SuppressWarnings("MethodDoesntCallSuperMethod")
@Override
public HashBiAssociation<T, U> clone() {
return new HashBiAssociation<>(associations.clone(), inverseAssociations.clone());
}
}