001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (C) 2012 Paul Ferraro 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package net.sf.hajdbc.balancer.roundrobin; 019 020import java.util.LinkedList; 021import java.util.Queue; 022import java.util.Set; 023 024import net.sf.hajdbc.Database; 025import net.sf.hajdbc.balancer.AbstractSetBalancer; 026 027/** 028 * Balancer implementation whose {@link #next()} implementation uses a circular FIFO queue. 029 * 030 * @author Paul Ferraro 031 * @param <D> either java.sql.Driver or javax.sql.DataSource 032 */ 033public class RoundRobinBalancer<P, D extends Database<P>> extends AbstractSetBalancer<P, D> 034{ 035 private Queue<D> databaseQueue = new LinkedList<D>(); 036 037 /** 038 * Constructs a new RoundRobinBalancer 039 * @param databases 040 */ 041 public RoundRobinBalancer(Set<D> databases) 042 { 043 super(databases); 044 045 for (D database: databases) 046 { 047 this.added(database); 048 } 049 } 050 051 /** 052 * {@inheritDoc} 053 * @see net.sf.hajdbc.balancer.AbstractSetBalancer#added(net.sf.hajdbc.Database) 054 */ 055 @Override 056 protected void added(D database) 057 { 058 int weight = database.getWeight(); 059 060 for (int i = 0; i < weight; ++i) 061 { 062 this.databaseQueue.add(database); 063 } 064 } 065 066 /** 067 * {@inheritDoc} 068 * @see net.sf.hajdbc.balancer.AbstractSetBalancer#removed(net.sf.hajdbc.Database) 069 */ 070 @Override 071 protected void removed(D database) 072 { 073 int weight = database.getWeight(); 074 075 for (int i = 0; i < weight; ++i) 076 { 077 this.databaseQueue.remove(database); 078 } 079 } 080 081 /** 082 * {@inheritDoc} 083 * @see net.sf.hajdbc.balancer.Balancer#next() 084 */ 085 @Override 086 public D next() 087 { 088 this.getLock().lock(); 089 090 try 091 { 092 if (this.databaseQueue.isEmpty()) 093 { 094 return this.primary(); 095 } 096 097 if (this.databaseQueue.size() == 1) 098 { 099 return this.databaseQueue.element(); 100 } 101 102 D database = this.databaseQueue.remove(); 103 104 this.databaseQueue.add(database); 105 106 return database; 107 } 108 finally 109 { 110 this.getLock().unlock(); 111 } 112 } 113 114 /** 115 * {@inheritDoc} 116 * @see net.sf.hajdbc.balancer.AbstractSetBalancer#cleared() 117 */ 118 @Override 119 protected void cleared() 120 { 121 this.databaseQueue.clear(); 122 } 123}