View Javadoc

1   /*
2    * Copyright (c) 1998-2002 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  
19  package jgroup.relacs.daemon;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.Map;
24  
25  import jgroup.core.EndPoint;
26  import jgroup.relacs.mss.MssHost;
27  
28  /**
29   * The <code> HostData</code> class
30   *
31   * @author  Alberto Montresor
32   * @since   Jgroup 0.1
33   */
34  final class HostData
35  {
36  
37    ////////////////////////////////////////////////////////////////////////////////////////////
38    // Fields
39    ////////////////////////////////////////////////////////////////////////////////////////////
40  
41    /** MssHost to which this information is related */
42    private final MssHost host;
43  
44    /** Coordinator table */ 
45    private MsgProp ctbl;
46  
47    /** If the host is leaving the group */ 
48    private boolean leaving;
49  
50    /** Index inside a view */ 
51    private int viewIndex;
52    
53    /** Version number */ 
54    private int version;
55  
56    /** Agreed version number */ 
57    private int agreed;
58  
59  
60    ////////////////////////////////////////////////////////////////////////////////////////////
61    // Constructors
62    ////////////////////////////////////////////////////////////////////////////////////////////
63  
64    /*
65     * Creates a new additional info object for host <code>host</code>.
66     */
67    HostData(MssHost host)
68    {
69      this.host   = host;
70      /*
71       * FIXED Hein: viewIndex was 0, but this may cause the agreement
72       * protocol to think that this host has a valid view index before
73       * a view has been installed which includes this host.
74       */
75      resetViewIndex();
76      version     = 0;
77      agreed      = 0;
78      leaving     = false;
79      ctbl        = null;
80    }
81  
82  
83    ////////////////////////////////////////////////////////////////////////////////////////////
84    // Methods
85    ////////////////////////////////////////////////////////////////////////////////////////////
86  
87    /**
88     *  Returns the endpoint associated with this host. 
89     */
90    EndPoint getEndPoint()
91    {
92      return host.getEndPoint();
93    }
94    
95    /**
96     *  Returns the <code>MssHost</code> associated with this object. 
97     */
98    MssHost getHost()
99    {
100     return host;
101   }
102 
103   /**
104    *  Returns the last proposal received from this host
105    */
106   MsgProp getProposal()
107   {
108     return ctbl;
109   }
110 
111   /**
112    *  Store the last proposal received from this host. 
113    */
114   void setProposal(MsgProp ctbl) 
115   {
116     this.ctbl = ctbl;
117   }
118 
119   /**
120    *  Returns true if this host is leaving.
121    */
122   boolean isLeaving()
123   {
124     return leaving;
125   }
126 
127   /**
128    *  Set this host as leaving.
129    */
130   void setLeaving(boolean leaving) 
131   {
132     this.leaving = leaving;
133   }
134 
135   /**
136    *  Returns the version number.
137    */
138   int getVersion()
139   {
140     return version;
141   }
142 
143   /**
144    *  Set the version number. 
145    */
146   void setVersion(int version) 
147   {
148     this.version = version;
149   }
150 
151   /**
152    *  Returns the agreed version number.
153    */
154   int getAgreed()
155   {
156     return agreed;
157   }
158 
159   /**
160    *  Set the agreed version number. 
161    */
162   void setAgreed(int agreed) 
163   {
164     Group.log.assertLog(this.agreed <= agreed, getEndPoint() +
165         ": new agreed is smaller ("+agreed+") than the previous ("+this.agreed+")");
166     if (this.agreed < agreed)
167       this.agreed = agreed;
168   }
169 
170   /**
171    *  Returns the index of this host in the current view.
172    */
173   int getViewIndex()
174   {
175     return viewIndex;
176   }
177 
178   /**
179    *  Set the index of this host in the current view.
180    */
181   void setViewIndex(int viewIndex) 
182   {
183     this.viewIndex = viewIndex;
184   }
185 
186   /**
187    *  Reset the view index of this host.  This indicates that this host
188    *  is not part of the current view.
189    */
190   void resetViewIndex()
191   {
192     viewIndex = -1;
193   }
194 
195   /**
196    *  Returns true if this host's view index is valid; false otherwise.
197    */
198   boolean hasValidViewIndex() 
199   {
200     return (viewIndex >= 0);
201   }
202 
203   /**
204    *  Resets the data associated to this host because a new incarnation
205    *  of it is present.
206    */
207   void newIncarnationId()
208   {
209     version = 0;
210     agreed  = 0;
211     resetViewIndex();
212     /*
213      * FIXED HEIN: A new incarnation may no longer be member of the same group.
214      * 
215      * FIXME this causes problems when a new member suddenly see an old member
216      * from a different partition.
217      *  
218      * It should be handled elsewhere; not related to a new incarnation, but that
219      * a member/host is no longer interested in this group.  I cannot recall when
220      * this caused problems, so we need to fix this after we can identify the
221      * problem fully.
222      */
223 //    leaving = true;
224   }
225 
226   /**
227    *  Creates a new version number.
228    */
229   void newVersion()
230   {
231     version++;
232     agreed++;
233   }
234   
235   public String toString()
236   {
237     StringBuilder buf = new StringBuilder("[HostData: ");
238     buf.append(host.getEndPoint().toString());
239     if (leaving)
240       buf.append(", leaving");
241     buf.append(", version=");
242     buf.append(version);
243     buf.append(", agreed=");
244     buf.append(agreed);
245     buf.append(", viewIndex=");
246     if (hasValidViewIndex())
247       buf.append(viewIndex);
248     else
249       buf.append("NO");
250     buf.append("]");
251     return buf.toString();
252   }
253 
254   ////////////////////////////////////////////////////////////////////////////////////////////
255   // Static methods
256   ////////////////////////////////////////////////////////////////////////////////////////////
257 
258   /**
259    *  Returns the list of <code>HostData</code> objects associated with
260    *  the hosts contained in the given <code>list</code>.  The
261    *  <code>HostData</code> objects are contained in <code>map</code>.
262    */
263   static List<HostData> extract(Map<EndPoint,HostData> map, EndPoint[] list)
264   {
265     List<HostData> ret = new ArrayList<HostData>();
266     for (int i=0; i < list.length; i++) {
267       HostData hostData = map.get(list[i]);
268       if (hostData != null)
269         ret.add(hostData);
270     }
271     return ret;
272   }
273 
274 } // END HostData