package org.jgroups;
import org.jgroups.util.Util;
import java.io.*;
import java.util.*;
/**
* This type of address represents a subset of the cluster members in which the total order properties must be applied,
* e.g. if the cluster membership is {A,B,C,D,E}, an AnycastAddress could be {D,E}.
*
* @author Pedro Ruivo
* @since 3.1
*/
public class AnycastAddress implements Address {
protected Collection<Address> destinations = new ArrayList<Address>(5);
private static final long serialVersionUID=-3133792315497822421L;
public AnycastAddress() {
}
public AnycastAddress(Collection<Address> addresses) {
addAll(addresses);
}
public AnycastAddress(Address ... addresses) {
add(addresses);
}
public void add(Address ... addresses) {
if(addresses == null || addresses.length == 0) return;
for(Address address: addresses)
_add(address);
}
protected void _add(Address address) {
if(!destinations.contains(address))
destinations.add(address);
}
public void addAll(Collection<Address> addresses) {
if(addresses != null && !addresses.isEmpty())
for(Address address: addresses)
_add(address);
}
public Collection<Address> getAddresses() {
return destinations;
}
public int size() {
int size = Global.INT_SIZE;
for(Address address : destinations) {
size += Util.size(address);
}
return size;
}
@Override
public String toString() {
return "AnycastAddress " + destinations;
}
@Override
public int hashCode() {
int hc = 0;
for(Address address : destinations) {
hc += address.hashCode();
}
return hc;
}
@Override
public boolean equals(Object obj) {
if(obj == null) return false;
if(!(obj instanceof AnycastAddress)) {
return false;
}
AnycastAddress other = (AnycastAddress) obj;
return other == this || (this.destinations.containsAll(other.destinations) &&
other.destinations.containsAll(this.destinations));
}
public int compareTo(Address o) {
int hc1, hc2;
if(this == o) return 0;
if(!(o instanceof AnycastAddress))
throw new ClassCastException("comparison between different classes: the other object is " +
(o != null? o.getClass() : o));
AnycastAddress other = (AnycastAddress) o;
hc1 = this.hashCode();
hc2 = other.hashCode();
if(hc1 == hc2) {
return this.destinations.size() < other.destinations.size() ? -1 :
this.destinations.size() > other.destinations.size() ? 1 : 0;
} else {
return hc1 < hc2 ? -1 : 1;
}
}
@Override
public void writeTo(DataOutput out) throws Exception {
Util.writeAddresses(destinations, out);
}
@Override
public void readFrom(DataInput in) throws Exception {
destinations = (Collection<Address>) Util.readAddresses(in, ArrayList.class);
}
@Override
public void writeExternal(ObjectOutput objectOutput) throws IOException {
try {
writeTo(objectOutput);
} catch (Exception e) {
throw new IOException(e);
}
}
@Override
public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
try {
readFrom(objectInput);
} catch (Exception e) {
throw new IOException(e);
}
}
}