KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > carol > cmi > RoundRobin


1 /*
2  * Copyright (C) 2002-2003, Simon Nieuviarts
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA
18  */

19 package org.objectweb.carol.cmi;
20
21 import java.util.Collection JavaDoc;
22 import java.util.Iterator JavaDoc;
23
24
25 public class RoundRobin extends StubLB {
26     private ClusterStubData csd;
27     private int len;
28     private StubData[] sd;
29     private double[] load;
30     private double minLoad;
31
32     /**
33      * Builds a round robin algorithm on a Collection of StubData objects.
34      * @param c a Collection of StubData objects.
35      */

36     public RoundRobin(ClusterStubData csd, Collection JavaDoc c) {
37         this.csd = csd;
38         len = c.size();
39         sd = new StubData[len];
40         load = new double[len];
41         Iterator JavaDoc it = c.iterator();
42         for (int i = 0; i < len; i++) {
43             StubData s = (StubData) it.next();
44             sd[i] = s;
45         }
46
47         /* a random start choice
48          */

49         for (int i = 0; i<SecureRandom.getInt(len); i++) {
50             load[i] = sd[i].getLoadIncr();
51         }
52     }
53
54     private synchronized void ensureCapacity(int minCapacity) {
55         int old = sd.length;
56         if (old >= minCapacity)
57             return;
58         int l = (old * 3) / 2 + 1;
59         if (l < minCapacity)
60             l = minCapacity;
61         StubData[] nsd = new StubData[l];
62         double[] nload = new double[l];
63         System.arraycopy(sd, 0, nsd, 0, old);
64         System.arraycopy(load, 0, nload, 0, old);
65         sd = nsd;
66         load = nload;
67     }
68
69     /**
70      * This method must be called only by the ClusterStubData to ensure integrity
71      * between this load balancer and the cluster stub.
72      * @see org.objectweb.carol.cmi.lb.StubLB#add(org.objectweb.carol.cmi.StubData)
73      */

74     synchronized void add(StubData sd) {
75         ensureCapacity(len + 1);
76         this.sd[len] = sd;
77         load[len] = minLoad;
78         len++;
79     }
80
81     /**
82      * This method must be called only by the ClusterStubData to ensure integrity
83      * between this load balancer and the cluster stub.
84      * @see org.objectweb.carol.cmi.lb.StubLB#remove(org.objectweb.carol.cmi.StubData)
85      */

86     synchronized void removeCallback(StubData s) {
87         for (int i=0; i<len; i++) {
88             if (sd[i] == s) {
89                 len--;
90                 sd[i] = sd[len];
91                 sd[len] = null;
92                 load[i] = load[len];
93                 return;
94             }
95         }
96     }
97
98     private static StubLBFilter emptyFilter = new StubLBFilter();
99
100     public synchronized StubData get() throws NoMoreStubException {
101         return get(emptyFilter);
102     }
103
104     public synchronized StubData get(StubLBFilter f) throws NoMoreStubException {
105         double min = Double.MAX_VALUE;
106         double minOk = Double.MAX_VALUE;
107         int index = -1;
108         for (int i=0; i<len; i++) {
109             double l = load[i];
110             if (l < minOk) {
111                 if (!f.contains(sd[i])) {
112                     minOk = l;
113                     index = i;
114                 }
115                 if (l < min) {
116                     min = l;
117                 }
118             }
119         }
120
121         if (index < 0) {
122             throw new NoMoreStubException();
123         }
124
125         // to avoid overflow, restart values when the min is relatively high
126
if (min >= 100.0) {
127             for (int i=0; i<len; i++) {
128                 load[i] -= min;
129             }
130             min = 0;
131         }
132
133         StubData s = sd[index];
134         load[index] += s.getLoadIncr();
135         return s;
136     }
137
138     /**
139      * @see org.objectweb.carol.cmi.StubLB#remove(java.rmi.StubData)
140      */

141     public void remove(StubData s) {
142         csd.removeStubData(s);
143     }
144 }
145
Popular Tags