001: // $Id: MergeView.java,v 1.7 2006/09/09 13:21:55 belaban Exp $
002:
003: package org.jgroups;
004:
005: import java.io.*;
006: import java.util.Iterator;
007: import java.util.Vector;
008:
009: /**
010: * A view that is sent as a result of a merge.
011: * Whenever a group splits into subgroups, e.g., due to a network partition,
012: * and later the subgroups merge back together, a MergeView instead of a View
013: * will be received by the application. The MergeView class is a subclass of
014: * View and contains as additional instance variable: the list of views that
015: * were merged. For example, if the group denoted by view V1:(p,q,r,s,t)
016: * splits into subgroups V2:(p,q,r) and V2:(s,t), the merged view might be
017: * V3:(p,q,r,s,t). In this case the MergeView would contain a list of 2 views:
018: * V2:(p,q,r) and V2:(s,t).
019: */
020: public class MergeView extends View {
021: /** Vector<View> */
022: protected Vector subgroups = null; // subgroups that merged into this single view (a list of Views)
023:
024: /**
025: * Used by externalization
026: */
027: public MergeView() {
028: }
029:
030: /**
031: * Creates a new view
032: *
033: * @param vid The view id of this view (can not be null)
034: * @param members Contains a list of all the members in the view, can be empty but not null.
035: * @param subgroups A list of Views representing the former subgroups
036: */
037: public MergeView(ViewId vid, Vector members, Vector subgroups) {
038: super (vid, members);
039: this .subgroups = subgroups;
040: }
041:
042: /**
043: * Creates a new view
044: *
045: * @param creator The creator of this view (can not be null)
046: * @param id The lamport timestamp of this view
047: * @param members Contains a list of all the members in the view, can be empty but not null.
048: * @param subgroups A list of Views representing the former subgroups
049: */
050: public MergeView(Address creator, long id, Vector members,
051: Vector subgroups) {
052: super (creator, id, members);
053: this .subgroups = subgroups;
054: }
055:
056: public Vector getSubgroups() {
057: return subgroups;
058: }
059:
060: /**
061: * creates a copy of this view
062: *
063: * @return a copy of this view
064: */
065: public Object clone() {
066: ViewId vid2 = vid != null ? (ViewId) vid.clone() : null;
067: Vector members2 = members != null ? (Vector) members.clone()
068: : null;
069: Vector subgroups2 = subgroups != null ? (Vector) subgroups
070: .clone() : null;
071: return new MergeView(vid2, members2, subgroups2);
072: }
073:
074: public String toString() {
075: StringBuffer sb = new StringBuffer();
076: sb.append("MergeView::").append(super .toString()).append(
077: ", subgroups=").append(subgroups);
078: return sb.toString();
079: }
080:
081: public void writeExternal(ObjectOutput out) throws IOException {
082: super .writeExternal(out);
083: out.writeObject(subgroups);
084: }
085:
086: public void readExternal(ObjectInput in) throws IOException,
087: ClassNotFoundException {
088: super .readExternal(in);
089: subgroups = (Vector) in.readObject();
090: }
091:
092: public void writeTo(DataOutputStream out) throws IOException {
093: super .writeTo(out);
094:
095: // write subgroups
096: int len = subgroups != null ? subgroups.size() : 0;
097: out.writeShort(len);
098: if (len == 0)
099: return;
100: View v;
101: for (Iterator it = subgroups.iterator(); it.hasNext();) {
102: v = (View) it.next();
103: if (v instanceof MergeView)
104: out.writeBoolean(true);
105: else
106: out.writeBoolean(false);
107: v.writeTo(out);
108: }
109: }
110:
111: public void readFrom(DataInputStream in) throws IOException,
112: IllegalAccessException, InstantiationException {
113: super .readFrom(in);
114: short len = in.readShort();
115: if (len > 0) {
116: View v;
117: subgroups = new Vector();
118: for (int i = 0; i < len; i++) {
119: boolean is_merge_view = in.readBoolean();
120: v = is_merge_view ? new MergeView() : new View();
121: v.readFrom(in);
122: subgroups.add(v);
123: }
124: }
125: }
126:
127: public int serializedSize() {
128: int retval = super .serializedSize();
129: retval += Global.SHORT_SIZE; // for size of subgroups vector
130:
131: if (subgroups == null)
132: return retval;
133: View v;
134: for (Iterator it = subgroups.iterator(); it.hasNext();) {
135: v = (View) it.next();
136: retval += Global.BYTE_SIZE; // boolean for View or MergeView
137: retval += v.serializedSize();
138: }
139: return retval;
140: }
141:
142: }
|