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 */ 021package net.sf.hajdbc.balancer; 022 023import java.util.ArrayList; 024import java.util.Collections; 025import java.util.List; 026import java.util.Random; 027 028import 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 */ 037public class RandomBalancer<D> extends AbstractBalancer<D> 038{ 039 private volatile List<Database<D>> databaseList = Collections.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 { 049 List<Database<D>> list = this.databaseList; 050 051 if (list.isEmpty()) 052 { 053 return this.databaseSet.first(); 054 } 055 056 int index = this.random.nextInt(list.size()); 057 058 return list.get(index); 059 } 060 061 /** 062 * @see net.sf.hajdbc.balancer.AbstractBalancer#added(net.sf.hajdbc.Database) 063 */ 064 @Override 065 protected void added(Database<D> database) 066 { 067 int weight = database.getWeight(); 068 069 if (weight > 0) 070 { 071 List<Database<D>> list = new ArrayList<Database<D>>(this.databaseList.size() + weight); 072 073 list.addAll(this.databaseList); 074 075 for (int i = 0; i < weight; ++i) 076 { 077 list.add(database); 078 } 079 080 this.databaseList = list; 081 } 082 } 083 084 /** 085 * @see net.sf.hajdbc.balancer.AbstractBalancer#removed(net.sf.hajdbc.Database) 086 */ 087 @Override 088 protected void removed(Database<D> database) 089 { 090 int weight = database.getWeight(); 091 092 if (weight > 0) 093 { 094 List<Database<D>> list = new ArrayList<Database<D>>(this.databaseList.size() - weight); 095 096 int index = this.databaseList.indexOf(database); 097 098 list.addAll(this.databaseList.subList(0, index)); 099 list.addAll(this.databaseList.subList(index + weight, this.databaseList.size())); 100 101 this.databaseList = list; 102 } 103 } 104 105 /** 106 * @see net.sf.hajdbc.balancer.AbstractBalancer#cleared() 107 */ 108 @Override 109 protected void cleared() 110 { 111 this.databaseList = Collections.emptyList(); 112 } 113}