Moving the cache away from DAO.

This commit is contained in:
marcins78@gmail.com
2012-04-03 14:34:24 +00:00
parent 087068c406
commit da8ad822dd
2 changed files with 128 additions and 217 deletions

View File

@@ -9,12 +9,16 @@ import com.gempukku.lotro.game.MutableCardCollection;
import com.gempukku.lotro.game.Player;
import com.gempukku.lotro.packs.PacksStorage;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CollectionsManager {
private ReentrantReadWriteLock _readWriteLock = new ReentrantReadWriteLock();
private Map<String, Map<String, CardCollection>> _collections = new ConcurrentHashMap<String, Map<String, CardCollection>>();
private PlayerDAO _playerDAO;
private CollectionDAO _collectionDAO;
@@ -27,25 +31,60 @@ public class CollectionsManager {
}
public void clearDBCache() {
_collectionDAO.clearCache();
_collections.clear();
}
public CardCollection getPlayerCollection(Player player, String collectionType) {
_readWriteLock.readLock().lock();
try {
final CardCollection collection = _collectionDAO.getCollectionForPlayer(player.getId(), collectionType);
Map<String, CardCollection> playerCollections = _collections.get(player.getName());
if (playerCollections != null) {
final CardCollection cardCollection = playerCollections.get(collectionType);
if (cardCollection != null)
return cardCollection;
}
final CardCollection collection = _collectionDAO.getPlayerCollection(player.getId(), collectionType);
if (collection != null) {
if (playerCollections == null) {
playerCollections = new ConcurrentHashMap<String, CardCollection>();
_collections.put(player.getName(), playerCollections);
}
playerCollections.put(collectionType, collection);
}
if (collection == null && collectionType.equals("permanent"))
return new DefaultCardCollection();
return collection;
} catch (SQLException exp) {
throw new RuntimeException("Unable to get player collection", exp);
} catch (IOException exp) {
throw new RuntimeException("Unable to get player collection", exp);
} finally {
_readWriteLock.readLock().unlock();
}
}
private void setPlayerCollection(Player player, String collectionType, CardCollection cardCollection) {
try {
_collectionDAO.setPlayerCollection(player.getId(), collectionType, cardCollection);
Map<String, CardCollection> playerCollections = _collections.get(player.getName());
if (playerCollections == null) {
playerCollections = new ConcurrentHashMap<String, CardCollection>();
_collections.put(player.getName(), playerCollections);
}
playerCollections.put(collectionType, cardCollection);
} catch (SQLException exp) {
throw new RuntimeException("Unable to store player collection", exp);
} catch (IOException exp) {
throw new RuntimeException("Unable to store player collection", exp);
}
}
public void addPlayerCollection(Player player, CollectionType collectionType, CardCollection cardCollection) {
_readWriteLock.writeLock().lock();
try {
_collectionDAO.setCollectionForPlayer(player.getId(), collectionType.getCode(), cardCollection);
setPlayerCollection(player, collectionType.getCode(), cardCollection);
addPackage(player, collectionType, cardCollection);
} finally {
_readWriteLock.writeLock().unlock();
@@ -62,6 +101,10 @@ public class CollectionsManager {
result.put(_playerDAO.getPlayer(playerCollection.getKey()), playerCollection.getValue());
return result;
} catch (SQLException exp) {
throw new RuntimeException("Unable to get players collection", exp);
} catch (IOException exp) {
throw new RuntimeException("Unable to get players collection", exp);
} finally {
_readWriteLock.readLock().unlock();
}
@@ -76,7 +119,7 @@ public class CollectionsManager {
MutableCardCollection mutableCardCollection = new DefaultCardCollection(playerCollection);
final CardCollection packContents = mutableCardCollection.openPack(packId, selection, packsStorage);
if (packContents != null) {
_collectionDAO.setCollectionForPlayer(player.getId(), collectionType.getCode(), mutableCardCollection);
setPlayerCollection(player, collectionType.getCode(), mutableCardCollection);
addPackage(player, collectionType, packContents);
}
return packContents;
@@ -97,7 +140,7 @@ public class CollectionsManager {
addedCards.addItem(item.getKey(), item.getValue());
}
_collectionDAO.setCollectionForPlayer(player.getId(), collectionType.getCode(), mutableCardCollection);
setPlayerCollection(player, collectionType.getCode(), mutableCardCollection);
addPackage(player, collectionType, addedCards);
}
} finally {
@@ -121,7 +164,7 @@ public class CollectionsManager {
return false;
mutableCardCollection.addItem(blueprintId2, count2);
_collectionDAO.setCollectionForPlayer(player.getId(), collectionType.getCode(), mutableCardCollection);
setPlayerCollection(player, collectionType.getCode(), mutableCardCollection);
return true;
}
return false;
@@ -140,7 +183,7 @@ public class CollectionsManager {
return false;
mutableCardCollection.addItem(blueprintId, 1);
_collectionDAO.setCollectionForPlayer(player.getId(), collectionType.getCode(), mutableCardCollection);
setPlayerCollection(player, collectionType.getCode(), mutableCardCollection);
return true;
}
return false;
@@ -159,7 +202,7 @@ public class CollectionsManager {
return false;
mutableCardCollection.addCurrency(currency);
_collectionDAO.setCollectionForPlayer(player.getId(), collectionType.getCode(), mutableCardCollection);
setPlayerCollection(player, collectionType.getCode(), mutableCardCollection);
return true;
}
return false;
@@ -176,7 +219,7 @@ public class CollectionsManager {
MutableCardCollection mutableCardCollection = new DefaultCardCollection(playerCollection);
mutableCardCollection.addCurrency(currency);
_collectionDAO.setCollectionForPlayer(player.getId(), collectionType.getCode(), mutableCardCollection);
setPlayerCollection(player, collectionType.getCode(), mutableCardCollection);
}
} finally {
_readWriteLock.writeLock().unlock();
@@ -190,7 +233,7 @@ public class CollectionsManager {
if (playerCollection != null) {
MutableCardCollection mutableCardCollection = new DefaultCardCollection(playerCollection);
if (mutableCardCollection.removeCurrency(currency)) {
_collectionDAO.setCollectionForPlayer(player.getId(), collectionType.getCode(), mutableCardCollection);
setPlayerCollection(player, collectionType.getCode(), mutableCardCollection);
return true;
}
}
@@ -200,80 +243,6 @@ public class CollectionsManager {
}
}
// public void moveCollectionToCollection(String player, CollectionType collectionFrom, CollectionType collectionTo) {
// moveCollectionToCollection(_playerDAO.getPlayer(player), collectionFrom, collectionTo);
// }
//
// public void moveCollectionToCollection(Player player, CollectionType collectionFrom, CollectionType collectionTo) {
// _readWriteLock.writeLock().lock();
// try {
// final CardCollection oldCollection = getPlayerCollection(player, collectionFrom.getCode());
// if (oldCollection != null) {
// final CardCollection newCollection = getPlayerCollection(player, collectionTo.getCode());
// if (newCollection != null) {
// MutableCardCollection mutableCardCollection = new DefaultCardCollection(newCollection);
// for (Map.Entry<String, Integer> item : oldCollection.getAll().entrySet())
// mutableCardCollection.addItem(item.getKey(), item.getValue());
//
// _collectionDAO.setCollectionForPlayer(player.getId(), collectionTo.getCode(), mutableCardCollection);
// addPackage(player, collectionTo, oldCollection);
// }
// }
// } finally {
// _readWriteLock.writeLock().unlock();
// }
// }
//
// public boolean commitTrade(CollectionType collectionType, Player playerOne, Player playerTwo, Map<String, Integer> itemsOfPlayerOne, Map<String, Integer> itemsOfPlayerTwo) {
// _readWriteLock.writeLock().lock();
// try {
// CardCollection collectionOne = getPlayerCollection(playerOne, collectionType.getCode());
// CardCollection collectionTwo = getPlayerCollection(playerTwo, collectionType.getCode());
//
// if (collectionOne == null || collectionTwo == null)
// return false;
//
// MutableCardCollection playerOneCollection = new DefaultCardCollection(collectionOne);
// MutableCardCollection playerTwoCollection = new DefaultCardCollection(collectionTwo);
//
// if (!removeItems(playerOneCollection, itemsOfPlayerOne))
// return false;
//
// if (!removeItems(playerTwoCollection, itemsOfPlayerTwo))
// return false;
//
// MutableCardCollection addedCardsPlayerOne = new DefaultCardCollection();
// MutableCardCollection addedCardsPlayerTwo = new DefaultCardCollection();
//
// addItems(playerOneCollection, addedCardsPlayerOne, itemsOfPlayerTwo);
// addItems(playerTwoCollection, addedCardsPlayerTwo, itemsOfPlayerOne);
//
// _collectionDAO.setCollectionForPlayer(playerOne.getId(), collectionType.getCode(), playerOneCollection);
// _collectionDAO.setCollectionForPlayer(playerTwo.getId(), collectionType.getCode(), playerTwoCollection);
//
// addPackage(playerOne, collectionType, addedCardsPlayerOne);
// addPackage(playerTwo, collectionType, addedCardsPlayerTwo);
//
// return true;
// } finally {
// _readWriteLock.writeLock().unlock();
// }
// }
//
// private boolean removeItems(MutableCardCollection collection, Map<String, Integer> items) {
// for (Map.Entry<String, Integer> item : items.entrySet())
// if (!collection.removeItem(item.getKey(), item.getValue()))
// return false;
// return true;
// }
//
// private void addItems(MutableCardCollection collection, MutableCardCollection addedCards, Map<String, Integer> items) {
// for (Map.Entry<String, Integer> item : items.entrySet()) {
// collection.addItem(item.getKey(), item.getValue());
// addedCards.addItem(item.getKey(), item.getValue());
// }
// }
private void addPackage(Player player, CollectionType collectionType, CardCollection cards) {
_deliveryService.addPackage(player, collectionType.getFullName(), cards);
}

View File

@@ -10,169 +10,111 @@ import java.io.InputStream;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CollectionDAO {
private DbAccess _dbAccess;
private CollectionSerializer _collectionSerializer;
private Map<Integer, Map<String, CardCollection>> _collections = new ConcurrentHashMap<Integer, Map<String, CardCollection>>();
public CollectionDAO(DbAccess dbAccess, CollectionSerializer collectionSerializer) {
_dbAccess = dbAccess;
_collectionSerializer = collectionSerializer;
}
public void clearCache() {
_collections.clear();
}
public CardCollection getCollectionForPlayer(int playerId, String type) {
Map<String, CardCollection> playerCollections = _collections.get(playerId);
if (playerCollections != null) {
CardCollection collection = playerCollections.get(type);
if (collection != null)
return collection;
}
CardCollection collection = getCollectionFromDB(playerId, type);
if (collection != null) {
Map<String, CardCollection> collectionsByType = _collections.get(playerId);
if (collectionsByType == null) {
collectionsByType = new ConcurrentHashMap<String, CardCollection>();
_collections.put(playerId, collectionsByType);
}
collectionsByType.put(type, collection);
return collection;
}
return null;
}
public Map<Integer, CardCollection> getPlayerCollectionsByType(String type) {
public Map<Integer, CardCollection> getPlayerCollectionsByType(String type) throws SQLException, IOException {
Connection connection = _dbAccess.getDataSource().getConnection();
try {
Connection connection = _dbAccess.getDataSource().getConnection();
PreparedStatement statement = connection.prepareStatement("select player_id, collection from collection where type=?");
try {
PreparedStatement statement = connection.prepareStatement("select player_id, collection from collection where type=?");
statement.setString(1, type);
ResultSet rs = statement.executeQuery();
try {
statement.setString(1, type);
ResultSet rs = statement.executeQuery();
try {
Map<Integer, CardCollection> playerCollections = new HashMap<Integer, CardCollection>();
while (rs.next()) {
int playerId = rs.getInt(1);
Blob blob = rs.getBlob(2);
Map<Integer, CardCollection> playerCollections = new HashMap<Integer, CardCollection>();
while (rs.next()) {
int playerId = rs.getInt(1);
Blob blob = rs.getBlob(2);
try {
InputStream inputStream = blob.getBinaryStream();
try {
InputStream inputStream = blob.getBinaryStream();
try {
playerCollections.put(playerId, _collectionSerializer.deserializeCollection(inputStream));
} finally {
inputStream.close();
}
playerCollections.put(playerId, _collectionSerializer.deserializeCollection(inputStream));
} finally {
blob.free();
inputStream.close();
}
} finally {
blob.free();
}
return playerCollections;
} finally {
rs.close();
}
return playerCollections;
} finally {
rs.close();
}
} finally {
statement.close();
}
} finally {
connection.close();
}
}
public CardCollection getPlayerCollection(int playerId, String type) throws SQLException, IOException {
Connection connection = _dbAccess.getDataSource().getConnection();
try {
PreparedStatement statement = connection.prepareStatement("select collection from collection where player_id=? and type=?");
try {
statement.setInt(1, playerId);
statement.setString(2, type);
ResultSet rs = statement.executeQuery();
try {
if (rs.next()) {
Blob blob = rs.getBlob(1);
try {
InputStream inputStream = blob.getBinaryStream();
try {
return _collectionSerializer.deserializeCollection(inputStream);
} finally {
inputStream.close();
}
} finally {
blob.free();
}
} else {
return null;
}
} finally {
statement.close();
rs.close();
}
} finally {
connection.close();
statement.close();
}
} catch (SQLException exp) {
throw new RuntimeException("Unable to get player collection from DB", exp);
} catch (IOException exp) {
throw new RuntimeException("Unable to get player collection from DB", exp);
} finally {
connection.close();
}
}
public void setCollectionForPlayer(int playerId, String type, CardCollection collection) {
if (!type.equals("default")) {
storeCollectionToDB(playerId, type, collection);
Map<String, CardCollection> collectionsByType = _collections.get(playerId);
if (collectionsByType == null) {
collectionsByType = new ConcurrentHashMap<String, CardCollection>();
_collections.put(playerId, collectionsByType);
}
collectionsByType.put(type, collection);
}
}
public void setPlayerCollection(int playerId, String type, CardCollection collection) throws SQLException, IOException {
CardCollection oldCollection = getPlayerCollection(playerId, type);
private CardCollection getCollectionFromDB(int playerId, String type) {
Connection connection = _dbAccess.getDataSource().getConnection();
try {
Connection connection = _dbAccess.getDataSource().getConnection();
String sql;
if (oldCollection == null)
sql = "insert into collection (collection, player_id, type) values (?, ?, ?)";
else
sql = "update collection set collection=? where player_id=? and type=?";
PreparedStatement statement = connection.prepareStatement(sql);
try {
PreparedStatement statement = connection.prepareStatement("select collection from collection where player_id=? and type=?");
try {
statement.setInt(1, playerId);
statement.setString(2, type);
ResultSet rs = statement.executeQuery();
try {
if (rs.next()) {
Blob blob = rs.getBlob(1);
try {
InputStream inputStream = blob.getBinaryStream();
try {
return _collectionSerializer.deserializeCollection(inputStream);
} finally {
inputStream.close();
}
} finally {
blob.free();
}
} else {
return null;
}
} finally {
rs.close();
}
} finally {
statement.close();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
_collectionSerializer.serializeCollection(collection, baos);
statement.setBlob(1, new ByteArrayInputStream(baos.toByteArray()));
statement.setInt(2, playerId);
statement.setString(3, type);
statement.execute();
} finally {
connection.close();
statement.close();
}
} catch (SQLException exp) {
throw new RuntimeException("Unable to get player collection from DB", exp);
} catch (IOException exp) {
throw new RuntimeException("Unable to get player collection from DB", exp);
}
}
private void storeCollectionToDB(int playerId, String type, CardCollection collection) {
CardCollection oldCollection = getCollectionFromDB(playerId, type);
try {
Connection connection = _dbAccess.getDataSource().getConnection();
try {
String sql;
if (oldCollection == null)
sql = "insert into collection (collection, player_id, type) values (?, ?, ?)";
else
sql = "update collection set collection=? where player_id=? and type=?";
PreparedStatement statement = connection.prepareStatement(sql);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
_collectionSerializer.serializeCollection(collection, baos);
statement.setBlob(1, new ByteArrayInputStream(baos.toByteArray()));
statement.setInt(2, playerId);
statement.setString(3, type);
statement.execute();
} finally {
statement.close();
}
} finally {
connection.close();
}
} catch (SQLException exp) {
throw new RuntimeException("Unable to get player collection from DB", exp);
} catch (IOException exp) {
throw new RuntimeException("Unable to get player collection from DB", exp);
} finally {
connection.close();
}
}
}