diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/CachedLeagueParticipationDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/CachedLeagueParticipationDAO.java new file mode 100644 index 000000000..dba455c2c --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/CachedLeagueParticipationDAO.java @@ -0,0 +1,79 @@ +package com.gempukku.lotro.db; + +import com.gempukku.lotro.db.vo.League; +import com.gempukku.lotro.game.Player; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class CachedLeagueParticipationDAO implements LeagueParticipationDAO { + private LeagueParticipationDAO _leagueParticipationDAO; + private ReadWriteLock _readWriteLock = new ReentrantReadWriteLock(); + + private Map> _cachedParticipants = new ConcurrentHashMap>(); + + public CachedLeagueParticipationDAO(LeagueParticipationDAO leagueParticipationDAO) { + _leagueParticipationDAO = leagueParticipationDAO; + } + + private String getLeagueCacheKey(League league) { + return league.getType(); + } + + @Override + public void userJoinsLeague(League league, Player player) { + _readWriteLock.writeLock().lock(); + try { + getLeagueParticipantsInWriteLock(league).add(player.getName()); + _leagueParticipationDAO.userJoinsLeague(league, player); + } finally { + _readWriteLock.writeLock().unlock(); + } + } + + @Override + public Collection getUsersParticipating(League league) { + _readWriteLock.readLock().lock(); + try { + Collection leagueParticipants = _cachedParticipants.get(getLeagueCacheKey(league)); + if (leagueParticipants == null) { + _readWriteLock.readLock().unlock(); + _readWriteLock.writeLock().lock(); + try { + leagueParticipants = getLeagueParticipantsInWriteLock(league); + } finally { + _readWriteLock.readLock().lock(); + _readWriteLock.writeLock().unlock(); + } + } + return Collections.unmodifiableCollection(leagueParticipants); + } finally { + _readWriteLock.readLock().unlock(); + } + } + + private Collection getLeagueParticipantsInWriteLock(League league) { + Set leagueParticipants; + leagueParticipants = _cachedParticipants.get(getLeagueCacheKey(league)); + if (leagueParticipants == null) { + leagueParticipants = new CopyOnWriteArraySet(_leagueParticipationDAO.getUsersParticipating(league)); + _cachedParticipants.put(getLeagueCacheKey(league), leagueParticipants); + } + return leagueParticipants; + } + + public void clearCache() { + _readWriteLock.writeLock().lock(); + try { + _cachedParticipants.clear(); + } finally { + _readWriteLock.writeLock().unlock(); + } + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbLeagueParticipationDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbLeagueParticipationDAO.java new file mode 100644 index 000000000..7ee1c327b --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbLeagueParticipationDAO.java @@ -0,0 +1,67 @@ +package com.gempukku.lotro.db; + +import com.gempukku.lotro.db.vo.League; +import com.gempukku.lotro.game.Player; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public class DbLeagueParticipationDAO implements LeagueParticipationDAO { + private DbAccess _dbAccess; + + public DbLeagueParticipationDAO(DbAccess dbAccess) { + _dbAccess = dbAccess; + } + + public void userJoinsLeague(League league, Player player) { + try { + Connection conn = _dbAccess.getDataSource().getConnection(); + try { + PreparedStatement statement = conn.prepareStatement("insert into league_participation (league_type, player_name) values (?,?)"); + try { + statement.setString(1, league.getType()); + statement.setString(2, player.getName()); + statement.execute(); + } finally { + statement.close(); + } + } finally { + conn.close(); + } + } catch (SQLException exp) { + throw new RuntimeException(exp); + } + } + + public Collection getUsersParticipating(League league) { + try { + Connection conn = _dbAccess.getDataSource().getConnection(); + try { + PreparedStatement statement = conn.prepareStatement("select player_name from league_participation where league_type=?"); + try { + statement.setString(1, league.getType()); + final ResultSet rs = statement.executeQuery(); + try { + Set result = new HashSet(); + while (rs.next()) + result.add(rs.getString(1)); + return result; + } finally { + rs.close(); + } + } finally { + statement.close(); + } + } finally { + conn.close(); + } + } catch (SQLException exp) { + throw new RuntimeException(exp); + } + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/LeagueParticipationDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/LeagueParticipationDAO.java index ffc795eea..731f06062 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/LeagueParticipationDAO.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/LeagueParticipationDAO.java @@ -3,55 +3,10 @@ package com.gempukku.lotro.db; import com.gempukku.lotro.db.vo.League; import com.gempukku.lotro.game.Player; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; +import java.util.Collection; -public class LeagueParticipationDAO { - private DbAccess _dbAccess; +public interface LeagueParticipationDAO { + public void userJoinsLeague(League league, Player player); - public LeagueParticipationDAO(DbAccess dbAccess) { - _dbAccess = dbAccess; - } - - public void userJoinsLeague(League league, Player player) throws SQLException { - Connection conn = _dbAccess.getDataSource().getConnection(); - try { - PreparedStatement statement = conn.prepareStatement("insert into league_participation (league_type, player_name) values (?,?)"); - try { - statement.setString(1, league.getType()); - statement.setString(2, player.getName()); - statement.execute(); - } finally { - statement.close(); - } - } finally { - conn.close(); - } - } - - public boolean isUserParticipating(League league, Player player) throws SQLException { - Connection conn = _dbAccess.getDataSource().getConnection(); - try { - PreparedStatement statement = conn.prepareStatement("select count(*) from league_participation where league_type=? and player_name=?"); - try { - statement.setString(1, league.getType()); - statement.setString(2, player.getName()); - final ResultSet rs = statement.executeQuery(); - try { - if (rs.next()) - return (rs.getInt(1) > 0); - else - return false; - } finally { - rs.close(); - } - } finally { - statement.close(); - } - } finally { - conn.close(); - } - } + public Collection getUsersParticipating(League league); } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueService.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueService.java index 0dea794fe..286014ebf 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueService.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueService.java @@ -28,15 +28,13 @@ public class LeagueService { private CachedLeaguePointsDAO _leaguePointsDao; // Cached on this layer private CachedLeagueMatchDAO _leagueMatchDao; - private LeagueParticipationDAO _leagueParticipationDAO; + private CachedLeagueParticipationDAO _leagueParticipationDAO; + private CollectionsManager _collectionsManager; private Map> _leagueStandings = new ConcurrentHashMap>(); private Map> _leagueSerieStandings = new ConcurrentHashMap>(); - private Map> _playersParticipating = new ConcurrentHashMap>(); - private Map> _playersNotParticipating = new ConcurrentHashMap>(); - private int _activeLeaguesLoadedDate; private List _activeLeagues; @@ -45,7 +43,7 @@ public class LeagueService { _leagueDao = leagueDao; _leaguePointsDao = new CachedLeaguePointsDAO(leaguePointsDao); _leagueMatchDao = new CachedLeagueMatchDAO(leagueMatchDao); - _leagueParticipationDAO = leagueParticipationDAO; + _leagueParticipationDAO = new CachedLeagueParticipationDAO(leagueParticipationDAO); _collectionsManager = collectionsManager; } @@ -56,6 +54,7 @@ public class LeagueService { _leagueMatchDao.clearCache(); _leaguePointsDao.clearCache(); + _leagueParticipationDAO.clearCache(); } private synchronized void ensureLoadedCurrentLeagues() { @@ -63,6 +62,7 @@ public class LeagueService { if (currentDate != _activeLeaguesLoadedDate) { _leagueMatchDao.clearCache(); _leaguePointsDao.clearCache(); + _leagueParticipationDAO.clearCache(); try { _activeLeagues = _leagueDao.loadActiveLeagues(currentDate); @@ -94,55 +94,18 @@ public class LeagueService { } } - public synchronized boolean isPlayerInLeague(League league, Player player) { - Set playersParticipating = _playersParticipating.get(league); - if (playersParticipating != null && playersParticipating.contains(player.getName())) - return true; - - Set playersNotParticipating = _playersNotParticipating.get(league); - if (playersNotParticipating != null && playersNotParticipating.contains(player.getName())) - return false; - - try { - final boolean userParticipating = _leagueParticipationDAO.isUserParticipating(league, player); - if (userParticipating) { - if (playersParticipating == null) { - playersParticipating = new HashSet(); - _playersParticipating.put(league, playersParticipating); - } - playersParticipating.add(player.getName()); - } else { - if (playersNotParticipating == null) { - playersNotParticipating = new HashSet(); - _playersNotParticipating.put(league, playersNotParticipating); - } - playersNotParticipating.add(player.getName()); - } - - return userParticipating; - } catch (SQLException e) { - throw new RuntimeException("Unable to retrieve information if user is part of the league"); - } + public boolean isPlayerInLeague(League league, Player player) { + return _leagueParticipationDAO.getUsersParticipating(league).contains(player.getName()); } - public synchronized boolean playerJoinsLeague(League league, Player player) { + public boolean playerJoinsLeague(League league, Player player) { if (isPlayerInLeague(league, player)) return false; int cost = league.getCost(); if (_collectionsManager.removeCurrencyFromPlayerCollection(player, new CollectionType("permanent", "My cards"), cost)) { - try { - _leagueParticipationDAO.userJoinsLeague(league, player); - Set notParticipating = _playersNotParticipating.get(league); - if (notParticipating != null) - notParticipating.remove(player.getName()); - Set participating = _playersParticipating.get(league); - if (participating != null) - participating.add(player.getName()); - league.getLeagueData().joinLeague(_collectionsManager, player, DateUtils.getCurrentDate()); - return true; - } catch (SQLException exp) { - throw new RuntimeException("Unable to add user to league"); - } + _leagueParticipationDAO.userJoinsLeague(league, player); + league.getLeagueData().joinLeague(_collectionsManager, player, DateUtils.getCurrentDate()); + return true; } else { return false; } diff --git a/gemp-lotr/gemp-lotr-web-server/src/main/java/com/gempukku/lotro/server/provider/DaoProvider.java b/gemp-lotr/gemp-lotr-web-server/src/main/java/com/gempukku/lotro/server/provider/DaoProvider.java index 3d559d812..e46a983ba 100644 --- a/gemp-lotr/gemp-lotr-web-server/src/main/java/com/gempukku/lotro/server/provider/DaoProvider.java +++ b/gemp-lotr/gemp-lotr-web-server/src/main/java/com/gempukku/lotro/server/provider/DaoProvider.java @@ -62,7 +62,7 @@ public class DaoProvider implements InjectableProvider { private synchronized Injectable getLeagueParticipationDaoSafely() { if (_leagueParticipationDAOInjectable == null) { - final LeagueParticipationDAO leagueParticipationDAO = new LeagueParticipationDAO(_dbAccess); + final LeagueParticipationDAO leagueParticipationDAO = new DbLeagueParticipationDAO(_dbAccess); _leagueParticipationDAOInjectable = new Injectable() { @Override public LeagueParticipationDAO getValue() {