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.registry;
20  
21  import java.rmi.RemoteException;
22  import java.util.Map;
23  
24  import jgroup.core.MemberId;
25  import jgroup.core.MemberTable;
26  import jgroup.core.VMID;
27  import jgroup.core.View;
28  import jgroup.util.IntList;
29  
30  import org.apache.log4j.Logger;
31  
32  /**
33   *
34   *
35   *  @author Alberto Montresor
36   *  @since Jgroup 0.4
37   */
38  final class ServerData
39  {
40  
41    ////////////////////////////////////////////////////////////////////////////////////////////
42    // Logger
43    ////////////////////////////////////////////////////////////////////////////////////////////
44  
45    /** Obtain logger for this class */
46    private static final Logger log = Logger.getLogger(ServerData.class);
47  
48  
49    ////////////////////////////////////////////////////////////////////////////////////////////
50    // Fields
51    ////////////////////////////////////////////////////////////////////////////////////////////
52  
53    /* Virtual machine identifier */
54    VMID vmid;
55  
56    /* List of active bindings */
57    BindingList bindings;
58  
59    /* List of removed bindings */
60    IntList removed;
61  
62    /* New binding ids inserted during last view */
63    private IntList nbids;
64  
65    /*
66     * Member table containing the status of other dependable registry
67     * instances.
68     */
69    MemberTable table;
70  
71  
72    ////////////////////////////////////////////////////////////////////////////////////////////
73    // Constructor
74    ////////////////////////////////////////////////////////////////////////////////////////////
75  
76    ServerData(VMID vmid)
77    {
78      this.vmid = vmid;
79      bindings = new BindingList();
80      removed = new IntList();
81      nbids = new IntList();
82      table = new MemberTable();
83    }
84  
85  
86    ////////////////////////////////////////////////////////////////////////////////////////////
87    // Methods
88    ////////////////////////////////////////////////////////////////////////////////////////////
89  
90    void add(int key, BindingList bl)
91    {
92      if (!removed.contains(key)) {
93        bindings.insert(bl);
94        nbids.insert(key);
95      }
96    }
97  
98    BindingList remove(int key)
99    {
100     removed.insert(key);
101     return (BindingList) bindings.remove(key);
102   }
103   
104   BindingList lookup(int key)
105   {
106     return (BindingList) bindings.lookup(key);
107   }
108 
109   void viewChange(View view)
110   {
111     table.viewChange(view);
112     MemberId[] members = table.members();
113     for (int i=0; i < members.length; i++) {
114       switch (table.getStatus(members[i])) {
115       case MemberTable.NEWMEMBER:
116         /* This is a new member */
117         if (log.isDebugEnabled())
118           log.debug("New member " + members[i]);
119         table.put(members[i], new IntList());
120         break;
121       case MemberTable.RECOVERING:
122         /* This member has crashed and then recovered */
123         if (log.isDebugEnabled())
124           log.debug("New incarnation " + members[i]);
125         table.put(members[i], new IntList());
126         break;
127       case MemberTable.SURVIVED:
128         /* This member is survived from the previous view */
129         if (log.isDebugEnabled())
130           log.debug("Inserting nbids: " + nbids);
131         IntList list = (IntList) table.get(members[i]);
132         if (log.isDebugEnabled())
133           log.debug("Before: list[" + members[i] + "] = " + list);
134         list.merge(nbids);
135         if (log.isDebugEnabled())
136           log.debug("After : list[" + members[i] + "] = " + list);
137         break;
138       }
139     }
140     nbids.clean();
141   }
142 
143 
144   BindingList[] getState(MemberId[] dests, MemberId me)
145   {
146     IntList slist = ((IntList) table.get(me));
147     slist = slist.copy();
148     if (log.isDebugEnabled())
149       log.debug("Starting slist: " + slist);
150     for (int i = 0; i < dests.length; i++) {
151       if (dests[i].equals(me))
152         slist.remove((IntList) table.get(dests[i]));
153     }
154     if (log.isDebugEnabled())
155       log.debug("Local removed: " + removed);
156     slist.remove(removed);
157     if (log.isDebugEnabled())
158       log.debug("Final: " + slist);
159     int[] bids = slist.toIntArray();
160     BindingList[] ret = new BindingList[bids.length];
161     BindingList scan = (BindingList) bindings.getFirst();
162     int i = 0;
163     while (scan != null && i < bids.length) {
164       if (scan.key == bids[i]) {
165         ret[i] = scan;
166         scan = (BindingList) scan.getNext();
167         i++;
168       } else if (scan.key < bids[i]) {
169         scan = (BindingList) scan.getNext();
170       } else {
171         i++;
172       }
173     }
174     return ret;
175   }
176 
177   void putState(Map<String, ServiceData> servicetable, IntList toremove, BindingList[] toadd)
178     throws ClassNotFoundException, RemoteException
179   {
180     toremove.remove(removed);
181     removed.merge(toremove);
182     int[] array = toremove.toIntArray();
183     for (int j = 0; j < array.length; j++) {
184       BindingList bl = (BindingList) bindings.remove(array[j]);
185       if (bl != null) {
186         ServiceData service = servicetable.get(bl.servicename);
187         if (service != null) {
188           service.remove(bl);
189           if (service.isEmpty())
190             servicetable.remove(bl.servicename);
191         }
192       }
193     }
194 
195     IntList nlist = new IntList();
196     for (int i = 0; i < toadd.length; i++) {
197       BindingList bl = toadd[i];
198       if (!removed.contains(bl.key)) {
199         ServiceData service = servicetable.get(bl.servicename);
200         if (service == null) {
201           service = new ServiceData(bl.serverClass, bl.servicename, bl.entry);
202           servicetable.put(bl.servicename, service);
203         }
204         service.add(bl);
205         bindings.insert(bl);
206         nlist.insert(bl.key);
207       }
208     }
209 
210     // Add the new bindings to list of new bindings
211     nbids.merge(nlist);
212   }
213 
214 } // END ServerData