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.db.vo.League;
|
||||||
import com.gempukku.lotro.game.Player;
|
import com.gempukku.lotro.game.Player;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.util.Collection;
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
public class LeagueParticipationDAO {
|
public interface LeagueParticipationDAO {
|
||||||
private DbAccess _dbAccess;
|
public void userJoinsLeague(League league, Player player);
|
||||||
|
|
||||||
public LeagueParticipationDAO(DbAccess dbAccess) {
|
public Collection<String> getUsersParticipating(League league);
|
||||||
_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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,13 @@ public class LeagueService {
|
|||||||
private CachedLeaguePointsDAO _leaguePointsDao;
|
private CachedLeaguePointsDAO _leaguePointsDao;
|
||||||
// Cached on this layer
|
// Cached on this layer
|
||||||
private CachedLeagueMatchDAO _leagueMatchDao;
|
private CachedLeagueMatchDAO _leagueMatchDao;
|
||||||
private LeagueParticipationDAO _leagueParticipationDAO;
|
private CachedLeagueParticipationDAO _leagueParticipationDAO;
|
||||||
|
|
||||||
private CollectionsManager _collectionsManager;
|
private CollectionsManager _collectionsManager;
|
||||||
|
|
||||||
private Map<League, List<PlayerStanding>> _leagueStandings = new ConcurrentHashMap<League, List<PlayerStanding>>();
|
private Map<League, List<PlayerStanding>> _leagueStandings = new ConcurrentHashMap<League, List<PlayerStanding>>();
|
||||||
private Map<LeagueSerieData, List<PlayerStanding>> _leagueSerieStandings = new ConcurrentHashMap<LeagueSerieData, 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 int _activeLeaguesLoadedDate;
|
||||||
private List<League> _activeLeagues;
|
private List<League> _activeLeagues;
|
||||||
|
|
||||||
@@ -45,7 +43,7 @@ public class LeagueService {
|
|||||||
_leagueDao = leagueDao;
|
_leagueDao = leagueDao;
|
||||||
_leaguePointsDao = new CachedLeaguePointsDAO(leaguePointsDao);
|
_leaguePointsDao = new CachedLeaguePointsDAO(leaguePointsDao);
|
||||||
_leagueMatchDao = new CachedLeagueMatchDAO(leagueMatchDao);
|
_leagueMatchDao = new CachedLeagueMatchDAO(leagueMatchDao);
|
||||||
_leagueParticipationDAO = leagueParticipationDAO;
|
_leagueParticipationDAO = new CachedLeagueParticipationDAO(leagueParticipationDAO);
|
||||||
_collectionsManager = collectionsManager;
|
_collectionsManager = collectionsManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +54,7 @@ public class LeagueService {
|
|||||||
|
|
||||||
_leagueMatchDao.clearCache();
|
_leagueMatchDao.clearCache();
|
||||||
_leaguePointsDao.clearCache();
|
_leaguePointsDao.clearCache();
|
||||||
|
_leagueParticipationDAO.clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void ensureLoadedCurrentLeagues() {
|
private synchronized void ensureLoadedCurrentLeagues() {
|
||||||
@@ -63,6 +62,7 @@ public class LeagueService {
|
|||||||
if (currentDate != _activeLeaguesLoadedDate) {
|
if (currentDate != _activeLeaguesLoadedDate) {
|
||||||
_leagueMatchDao.clearCache();
|
_leagueMatchDao.clearCache();
|
||||||
_leaguePointsDao.clearCache();
|
_leaguePointsDao.clearCache();
|
||||||
|
_leagueParticipationDAO.clearCache();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_activeLeagues = _leagueDao.loadActiveLeagues(currentDate);
|
_activeLeagues = _leagueDao.loadActiveLeagues(currentDate);
|
||||||
@@ -94,55 +94,18 @@ public class LeagueService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean isPlayerInLeague(League league, Player player) {
|
public boolean isPlayerInLeague(League league, Player player) {
|
||||||
Set<String> playersParticipating = _playersParticipating.get(league);
|
return _leagueParticipationDAO.getUsersParticipating(league).contains(player.getName());
|
||||||
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 synchronized boolean playerJoinsLeague(League league, Player player) {
|
public boolean playerJoinsLeague(League league, Player player) {
|
||||||
if (isPlayerInLeague(league, player))
|
if (isPlayerInLeague(league, player))
|
||||||
return false;
|
return false;
|
||||||
int cost = league.getCost();
|
int cost = league.getCost();
|
||||||
if (_collectionsManager.removeCurrencyFromPlayerCollection(player, new CollectionType("permanent", "My cards"), cost)) {
|
if (_collectionsManager.removeCurrencyFromPlayerCollection(player, new CollectionType("permanent", "My cards"), cost)) {
|
||||||
try {
|
_leagueParticipationDAO.userJoinsLeague(league, player);
|
||||||
_leagueParticipationDAO.userJoinsLeague(league, player);
|
league.getLeagueData().joinLeague(_collectionsManager, player, DateUtils.getCurrentDate());
|
||||||
Set<String> notParticipating = _playersNotParticipating.get(league);
|
return true;
|
||||||
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");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class DaoProvider implements InjectableProvider<Context, Type> {
|
|||||||
|
|
||||||
private synchronized Injectable<LeagueParticipationDAO> getLeagueParticipationDaoSafely() {
|
private synchronized Injectable<LeagueParticipationDAO> getLeagueParticipationDaoSafely() {
|
||||||
if (_leagueParticipationDAOInjectable == null) {
|
if (_leagueParticipationDAOInjectable == null) {
|
||||||
final LeagueParticipationDAO leagueParticipationDAO = new LeagueParticipationDAO(_dbAccess);
|
final LeagueParticipationDAO leagueParticipationDAO = new DbLeagueParticipationDAO(_dbAccess);
|
||||||
_leagueParticipationDAOInjectable = new Injectable<LeagueParticipationDAO>() {
|
_leagueParticipationDAOInjectable = new Injectable<LeagueParticipationDAO>() {
|
||||||
@Override
|
@Override
|
||||||
public LeagueParticipationDAO getValue() {
|
public LeagueParticipationDAO getValue() {
|
||||||
|
|||||||
Reference in New Issue
Block a user