Better caching for league participation (separate class).
This commit is contained in:
@@ -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<String, Set<String>> _cachedParticipants = new ConcurrentHashMap<String, Set<String>>();
|
||||
|
||||
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<String> getUsersParticipating(League league) {
|
||||
_readWriteLock.readLock().lock();
|
||||
try {
|
||||
Collection<String> 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<String> getLeagueParticipantsInWriteLock(League league) {
|
||||
Set<String> leagueParticipants;
|
||||
leagueParticipants = _cachedParticipants.get(getLeagueCacheKey(league));
|
||||
if (leagueParticipants == null) {
|
||||
leagueParticipants = new CopyOnWriteArraySet<String>(_leagueParticipationDAO.getUsersParticipating(league));
|
||||
_cachedParticipants.put(getLeagueCacheKey(league), leagueParticipants);
|
||||
}
|
||||
return leagueParticipants;
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
_readWriteLock.writeLock().lock();
|
||||
try {
|
||||
_cachedParticipants.clear();
|
||||
} finally {
|
||||
_readWriteLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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<String> result = new HashSet<String>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> getUsersParticipating(League league);
|
||||
}
|
||||
|
||||
@@ -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<League, List<PlayerStanding>> _leagueStandings = new ConcurrentHashMap<League, List<PlayerStanding>>();
|
||||
private Map<LeagueSerieData, List<PlayerStanding>> _leagueSerieStandings = new ConcurrentHashMap<LeagueSerieData, List<PlayerStanding>>();
|
||||
|
||||
private Map<League, Set<String>> _playersParticipating = new ConcurrentHashMap<League, Set<String>>();
|
||||
private Map<League, Set<String>> _playersNotParticipating = new ConcurrentHashMap<League, Set<String>>();
|
||||
|
||||
private int _activeLeaguesLoadedDate;
|
||||
private List<League> _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<String> playersParticipating = _playersParticipating.get(league);
|
||||
if (playersParticipating != null && playersParticipating.contains(player.getName()))
|
||||
return true;
|
||||
|
||||
Set<String> 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<String>();
|
||||
_playersParticipating.put(league, playersParticipating);
|
||||
}
|
||||
playersParticipating.add(player.getName());
|
||||
} else {
|
||||
if (playersNotParticipating == null) {
|
||||
playersNotParticipating = new HashSet<String>();
|
||||
_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<String> notParticipating = _playersNotParticipating.get(league);
|
||||
if (notParticipating != null)
|
||||
notParticipating.remove(player.getName());
|
||||
Set<String> 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;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class DaoProvider implements InjectableProvider<Context, Type> {
|
||||
|
||||
private synchronized Injectable<LeagueParticipationDAO> getLeagueParticipationDaoSafely() {
|
||||
if (_leagueParticipationDAOInjectable == null) {
|
||||
final LeagueParticipationDAO leagueParticipationDAO = new LeagueParticipationDAO(_dbAccess);
|
||||
final LeagueParticipationDAO leagueParticipationDAO = new DbLeagueParticipationDAO(_dbAccess);
|
||||
_leagueParticipationDAOInjectable = new Injectable<LeagueParticipationDAO>() {
|
||||
@Override
|
||||
public LeagueParticipationDAO getValue() {
|
||||
|
||||
Reference in New Issue
Block a user