package org.jgroups; import org.jgroups.util.Streamable; import org.jgroups.util.Util; import java.io.*; import java.util.*; /** * A view is a local representation of the current membership of a group. Only one view is installed * in a channel at a time. Views contain the address of its creator, an ID and a list of member * addresses. These addresses are ordered, and the first address is always the coordinator of the * view. This way, each member of the group knows who the new coordinator will be if the current one * crashes or leaves the group. The views are sent between members using the VIEW_CHANGE event * * @since 2.0 * @author Bela Ban */ public class View implements Comparable<View>, Streamable, Iterable<Address> { /** * A view is uniquely identified by its ViewID. The view id contains the creator address and a * Lamport time. The Lamport time is the highest timestamp seen or sent from a view. if a view * change comes in with a lower Lamport time, the event is discarded. */ protected ViewId vid; /** * A list containing all the members of the view.This list is always ordered, with the * coordinator being the first member. the second member will be the new coordinator if the * current one disappears or leaves the group. */ protected List<Address> members; /** * Creates an empty view, should not be used, only used by (de-)serialization */ public View() { } /** * Creates a new view * * @param vid The view id of this view (can not be null) * @param members Contains a list of all the members in the view, can be empty but not null. */ public View(ViewId vid, List<Address> members) { this.vid=vid; this.members=new ArrayList<Address>(members); } /** * Creates a new view * * @param creator The creator of this view (can not be null) * @param id The lamport timestamp of this view * @param members Contains a list of all the members in the view, can be empty but not null. */ public View(Address creator, long id, List<Address> members) { this(new ViewId(creator, id), members); } /** * Returns the view ID of this view * if this view was created with the empty constructur, null will be returned * * @return the view ID of this view */ public ViewId getVid() {return vid;} public ViewId getViewId() {return vid;} /** * Returns the creator of this view * if this view was created with the empty constructur, null will be returned * * @return the creator of this view in form of an Address object */ public Address getCreator() { return vid.getCreator(); } /** * Returns a reference to the List of members (ordered) * Do NOT change this list, hence your will invalidate the view * Make a copy if you have to modify it. * * @return a reference to the ordered list of members in this view */ public List<Address> getMembers() { return Collections.unmodifiableList(members); } /** * Returns true, if this view contains a certain member * * @param mbr - the address of the member, * @return true if this view contains the member, false if it doesn't * if the argument mbr is null, this operation returns false */ public boolean containsMember(Address mbr) { return mbr != null && members.contains(mbr); } public int compareTo(View o) { return vid.compareTo(o.vid); } public boolean equals(Object obj) { return obj instanceof View && (this == obj || compareTo((View)obj) == 0); } public int hashCode() { return vid.hashCode(); } /** * Returns the number of members in this view * * @return the number of members in this view 0..n */ public int size() { return members.size(); } public View copy() { return new View(vid.copy(), members); } public String toString() { StringBuilder sb=new StringBuilder(64); sb.append(vid).append(" "); if(members != null) sb.append("[").append(Util.printListWithDelimiter(members, ", ", Util.MAX_LIST_PRINT_SIZE)).append("]"); return sb.toString(); } public void writeTo(DataOutput out) throws Exception { vid.writeTo(out); Util.writeAddresses(members, out); } @SuppressWarnings("unchecked") public void readFrom(DataInput in) throws Exception { vid=new ViewId(); vid.readFrom(in); members=(List<Address>)Util.readAddresses(in, ArrayList.class); } public int serializedSize() { return (int)(vid.serializedSize() + Util.size(members)); } public Iterator<Address> iterator() { return members.iterator(); } }