Add Association data type
This commit is contained in:
parent
4b11b7fd94
commit
c755b57e0c
107
src/main/java/org/warp/commonutils/type/Association.java
Normal file
107
src/main/java/org/warp/commonutils/type/Association.java
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package org.warp.commonutils.type;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One to many relationship (not overlapping)
|
||||||
|
*
|
||||||
|
* o ------- o
|
||||||
|
* +--- o
|
||||||
|
* o ---+--- o
|
||||||
|
* +--- o
|
||||||
|
* o ------- o
|
||||||
|
* o ------- o
|
||||||
|
* o ---+--- o
|
||||||
|
* +--- o
|
||||||
|
*
|
||||||
|
* @param <T> Source type
|
||||||
|
* @param <U> Destination type
|
||||||
|
*/
|
||||||
|
public interface Association<T, U> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link source to dest
|
||||||
|
* @param src Source
|
||||||
|
* @param dest Destination
|
||||||
|
* @return true if linked, false if it was already linked with that destination
|
||||||
|
*/
|
||||||
|
boolean link(T src, U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink only if src is linked with dest
|
||||||
|
* @param src Source
|
||||||
|
* @param dest Destination
|
||||||
|
* @return true if unlinked, false if not present
|
||||||
|
*/
|
||||||
|
boolean unlink(T src, U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink
|
||||||
|
* @param src Source
|
||||||
|
* @return previous linked destinations
|
||||||
|
*/
|
||||||
|
Set<U> unlink(T src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink
|
||||||
|
* @param dest Destination
|
||||||
|
* @return previous linked source
|
||||||
|
*/
|
||||||
|
Optional<T> unlinkFromSource(U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if link exists
|
||||||
|
* @param src Source
|
||||||
|
* @return true if source it's linked with at least 1 destination
|
||||||
|
*/
|
||||||
|
default boolean hasAnyLink(T src) {
|
||||||
|
return !getLinks(src).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if link exists
|
||||||
|
* @param dest Destination
|
||||||
|
* @return true if destination is linked with a source
|
||||||
|
*/
|
||||||
|
default boolean hasLinkSource(U dest) {
|
||||||
|
return getLinkSource(dest).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if link exists
|
||||||
|
* @param src Source
|
||||||
|
* @param dest Destination
|
||||||
|
* @return true if source and destination are linked together
|
||||||
|
*/
|
||||||
|
boolean hasLink(T src, U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a link destination
|
||||||
|
* @param src Source
|
||||||
|
* @return Existing linked destinations
|
||||||
|
*/
|
||||||
|
Set<U> getLinks(T src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a link source
|
||||||
|
* @param dest Source
|
||||||
|
* @return Source if the link exists
|
||||||
|
*/
|
||||||
|
Optional<T> getLinkSource(U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all links
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the count of existing links
|
||||||
|
* @return size
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
|
static <T, U> Association<T, U> synchronize(Association<T, U> association) {
|
||||||
|
return new SynchronizedAssociation(association);
|
||||||
|
}
|
||||||
|
}
|
106
src/main/java/org/warp/commonutils/type/BiAssociation.java
Normal file
106
src/main/java/org/warp/commonutils/type/BiAssociation.java
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package org.warp.commonutils.type;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One to one relationship
|
||||||
|
*
|
||||||
|
* o ------- o
|
||||||
|
* o ------- o
|
||||||
|
* o ------- o
|
||||||
|
* o ------- o
|
||||||
|
* o ------- o
|
||||||
|
* o ------- o
|
||||||
|
* o ------- o
|
||||||
|
* o ------- o
|
||||||
|
*
|
||||||
|
* @param <T> Source type
|
||||||
|
* @param <U> Destination type
|
||||||
|
*/
|
||||||
|
public interface BiAssociation<T, U> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link source to dest
|
||||||
|
* @param src Source
|
||||||
|
* @param dest Destination
|
||||||
|
* @return previous value if it was already linked
|
||||||
|
*/
|
||||||
|
Optional<U> link(T src, U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink only if src is linked with dest
|
||||||
|
* @param src Source
|
||||||
|
* @param dest Destination
|
||||||
|
* @return true if unlinked, false if not present
|
||||||
|
*/
|
||||||
|
boolean unlink(T src, U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink
|
||||||
|
* @param src Source
|
||||||
|
* @return previous linked destination
|
||||||
|
*/
|
||||||
|
Optional<U> unlink(T src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink
|
||||||
|
* @param dest Destination
|
||||||
|
* @return previous linked source
|
||||||
|
*/
|
||||||
|
Optional<T> unlinkFromSource(U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if link exists
|
||||||
|
* @param src Source
|
||||||
|
* @return true if source it's linked with a destination
|
||||||
|
*/
|
||||||
|
default boolean hasLink(T src) {
|
||||||
|
return getLink(src).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if link exists
|
||||||
|
* @param dest Destination
|
||||||
|
* @return true if destination is linked with a source
|
||||||
|
*/
|
||||||
|
default boolean hasLinkSource(U dest) {
|
||||||
|
return getLinkSource(dest).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if link exists
|
||||||
|
* @param src Source
|
||||||
|
* @param dest Destination
|
||||||
|
* @return true if source and destination are linked together
|
||||||
|
*/
|
||||||
|
boolean hasLink(T src, U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a link destination
|
||||||
|
* @param src Source
|
||||||
|
* @return Destination if the link exists
|
||||||
|
*/
|
||||||
|
Optional<U> getLink(T src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a link source
|
||||||
|
* @param dest Source
|
||||||
|
* @return Source if the link exists
|
||||||
|
*/
|
||||||
|
Optional<T> getLinkSource(U dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all links
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the count of existing links
|
||||||
|
* @return size
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
|
static <T, U> BiAssociation<T, U> synchronize(BiAssociation<T, U> association) {
|
||||||
|
return new SynchronizedBiAssociation(association);
|
||||||
|
}
|
||||||
|
}
|
166
src/main/java/org/warp/commonutils/type/HashAssociation.java
Normal file
166
src/main/java/org/warp/commonutils/type/HashAssociation.java
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
package org.warp.commonutils.type;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class HashAssociation<T, U> implements Association<T, U> {
|
||||||
|
|
||||||
|
private final Object2ObjectOpenHashMap<T, ObjectOpenHashSet<U>> associations;
|
||||||
|
private final Object2ObjectOpenHashMap<U, T> inverseAssociations;
|
||||||
|
|
||||||
|
public HashAssociation() {
|
||||||
|
this.associations = new Object2ObjectOpenHashMap<>();
|
||||||
|
this.inverseAssociations = new Object2ObjectOpenHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashAssociation(Object2ObjectOpenHashMap<T, ObjectOpenHashSet<U>> associations,
|
||||||
|
Object2ObjectOpenHashMap<U, T> inverseAssociations) {
|
||||||
|
this.associations = associations;
|
||||||
|
this.inverseAssociations = inverseAssociations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean link(T src, U dest) {
|
||||||
|
Objects.requireNonNull(src);
|
||||||
|
Objects.requireNonNull(dest);
|
||||||
|
// If the destination is associated to null
|
||||||
|
var previousSrc = inverseAssociations.get(dest);
|
||||||
|
|
||||||
|
// Return if the association already exists
|
||||||
|
if (src.equals(previousSrc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the previous association if present
|
||||||
|
if (previousSrc != null) {
|
||||||
|
inverseAssociations.remove(dest);
|
||||||
|
var destinations = associations.get(previousSrc);
|
||||||
|
destinations.remove(dest);
|
||||||
|
if (destinations.isEmpty()) {
|
||||||
|
associations.remove(previousSrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!associations.computeIfAbsent(src, s -> new ObjectOpenHashSet<>(0)).add(dest)) {
|
||||||
|
throw new IllegalStateException("Association was partially linked");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean unlink(T src, U dest) {
|
||||||
|
Objects.requireNonNull(src);
|
||||||
|
Objects.requireNonNull(dest);
|
||||||
|
|
||||||
|
var linkedSrc = inverseAssociations.get(dest);
|
||||||
|
|
||||||
|
// Check if the link is different
|
||||||
|
if (!Objects.equals(src, linkedSrc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inverseAssociations.remove(dest);
|
||||||
|
var destinations = associations.get(src);
|
||||||
|
if (!destinations.remove(dest)) {
|
||||||
|
throw new IllegalStateException("Association was partially linked");
|
||||||
|
}
|
||||||
|
if (destinations.isEmpty()) {
|
||||||
|
associations.remove(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<U> unlink(T src) {
|
||||||
|
Objects.requireNonNull(src);
|
||||||
|
|
||||||
|
var destinations = associations.remove(src);
|
||||||
|
|
||||||
|
if (destinations == null) {
|
||||||
|
return Set.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (U destination : destinations) {
|
||||||
|
if (!Objects.equals(src, inverseAssociations.remove(destination))) {
|
||||||
|
throw new IllegalStateException("Association was partially linked");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return destinations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<T> unlinkFromSource(U dest) {
|
||||||
|
Objects.requireNonNull(dest);
|
||||||
|
|
||||||
|
var previousSrc = inverseAssociations.remove(dest);
|
||||||
|
|
||||||
|
if (previousSrc == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
var destinations = associations.get(previousSrc);
|
||||||
|
destinations.remove(dest);
|
||||||
|
if (destinations.isEmpty()) {
|
||||||
|
associations.remove(previousSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(previousSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasAnyLink(T src) {
|
||||||
|
Objects.requireNonNull(src);
|
||||||
|
var destinations = associations.get(src);
|
||||||
|
return destinations != null && !destinations.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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(src, inverseAssociations.get(dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<U> getLinks(T src) {
|
||||||
|
Objects.requireNonNull(src);
|
||||||
|
return associations.get(src).clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 HashAssociation<T, U> clone() {
|
||||||
|
var associationsClone = associations.clone();
|
||||||
|
associationsClone.replaceAll((item, destinations) -> destinations.clone());
|
||||||
|
return new HashAssociation<>(associationsClone, inverseAssociations.clone());
|
||||||
|
}
|
||||||
|
}
|
142
src/main/java/org/warp/commonutils/type/HashBiAssociation.java
Normal file
142
src/main/java/org/warp/commonutils/type/HashBiAssociation.java
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package org.warp.commonutils.type;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class SynchronizedAssociation<T, U> implements Association<T, U> {
|
||||||
|
|
||||||
|
private final Association<T,U> association;
|
||||||
|
private final Object lock;
|
||||||
|
|
||||||
|
public SynchronizedAssociation(Association<T, U> association) {
|
||||||
|
this.association = association;
|
||||||
|
this.lock = new Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SynchronizedAssociation(Association<T, U> association, Object lock) {
|
||||||
|
this.association = association;
|
||||||
|
this.lock = lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean link(T src, U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.link(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean unlink(T src, U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.unlink(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<U> unlink(T src) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.unlink(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<T> unlinkFromSource(U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.unlinkFromSource(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasAnyLink(T src) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.hasAnyLink(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasLinkSource(U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.hasLinkSource(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasLink(T src, U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.hasLink(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<U> getLinks(T src) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.getLinks(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<T> getLinkSource(U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.getLinkSource(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
synchronized (lock) {
|
||||||
|
association.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package org.warp.commonutils.type;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class SynchronizedBiAssociation<T, U> implements BiAssociation<T, U> {
|
||||||
|
|
||||||
|
private final BiAssociation<T,U> association;
|
||||||
|
private final Object lock;
|
||||||
|
|
||||||
|
public SynchronizedBiAssociation(BiAssociation<T, U> association) {
|
||||||
|
this.association = association;
|
||||||
|
this.lock = new Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SynchronizedBiAssociation(BiAssociation<T, U> association, Object lock) {
|
||||||
|
this.association = association;
|
||||||
|
this.lock = lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<U> link(T src, U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.link(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean unlink(T src, U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.unlink(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<U> unlink(T src) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.unlink(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<T> unlinkFromSource(U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.unlinkFromSource(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasLink(T src) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.hasLink(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasLinkSource(U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.hasLinkSource(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasLink(T src, U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.hasLink(src, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<U> getLink(T src) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.getLink(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<T> getLinkSource(U dest) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.getLinkSource(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
synchronized (lock) {
|
||||||
|
association.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
synchronized (lock) {
|
||||||
|
return association.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user