001: /*
002: * HA-JDBC: High-Availability JDBC
003: * Copyright (c) 2004-2007 Paul Ferraro
004: *
005: * This library is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU Lesser General Public License as published by the
007: * Free Software Foundation; either version 2.1 of the License, or (at your
008: * option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
013: * for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public License
016: * along with this library; if not, write to the Free Software Foundation,
017: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Contact: ferraro@users.sourceforge.net
020: */
021: package net.sf.hajdbc.balancer;
022:
023: import java.util.ArrayList;
024: import java.util.Collections;
025: import java.util.List;
026: import java.util.Random;
027:
028: import net.sf.hajdbc.Database;
029:
030: /**
031: * Balancer implementation whose {@link #next()} implementation returns a random database.
032: * The probability that a given database will be returned is: <em>weight / total-weight</em>.
033: *
034: * @author Paul Ferraro
035: * @param <D> either java.sql.Driver or javax.sql.DataSource
036: */
037: public class RandomBalancer<D> extends AbstractBalancer<D> {
038: private volatile List<Database<D>> databaseList = Collections
039: .emptyList();
040:
041: private Random random = new Random();
042:
043: /**
044: * @see net.sf.hajdbc.Balancer#next()
045: */
046: @Override
047: public Database<D> next() {
048: List<Database<D>> list = this .databaseList;
049:
050: if (list.isEmpty()) {
051: return this .databaseSet.first();
052: }
053:
054: int index = this .random.nextInt(list.size());
055:
056: return list.get(index);
057: }
058:
059: /**
060: * @see net.sf.hajdbc.balancer.AbstractBalancer#added(net.sf.hajdbc.Database)
061: */
062: @Override
063: protected void added(Database<D> database) {
064: int weight = database.getWeight();
065:
066: if (weight > 0) {
067: List<Database<D>> list = new ArrayList<Database<D>>(
068: this .databaseList.size() + weight);
069:
070: list.addAll(this .databaseList);
071:
072: for (int i = 0; i < weight; ++i) {
073: list.add(database);
074: }
075:
076: this .databaseList = list;
077: }
078: }
079:
080: /**
081: * @see net.sf.hajdbc.balancer.AbstractBalancer#removed(net.sf.hajdbc.Database)
082: */
083: @Override
084: protected void removed(Database<D> database) {
085: int weight = database.getWeight();
086:
087: if (weight > 0) {
088: List<Database<D>> list = new ArrayList<Database<D>>(
089: this .databaseList.size() - weight);
090:
091: int index = this .databaseList.indexOf(database);
092:
093: list.addAll(this .databaseList.subList(0, index));
094: list.addAll(this .databaseList.subList(index + weight,
095: this .databaseList.size()));
096:
097: this .databaseList = list;
098: }
099: }
100:
101: /**
102: * @see net.sf.hajdbc.balancer.AbstractBalancer#cleared()
103: */
104: @Override
105: protected void cleared() {
106: this.databaseList = Collections.emptyList();
107: }
108: }
|