Commit fffb7803 authored by Matt Tucker's avatar Matt Tucker Committed by matt

Optimized for the case that there are no privacy lists (JM-762).

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@4289 b35dd754-fafc-0310-a699-88a17e54d16e
parent 516a1dbb
......@@ -22,8 +22,10 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Provider for the privacy lists system. Privacy lists are read and written
......@@ -33,6 +35,8 @@ import java.util.concurrent.LinkedBlockingQueue;
*/
public class PrivacyListProvider {
private static final String PRIVACY_LIST_COUNT =
"SELECT count(*) from jivePrivacyList";
private static final String LOAD_LIST_NAMES =
"SELECT name, isDefault FROM jivePrivacyList WHERE username=?";
private static final String LOAD_PRIVACY_LIST =
......@@ -53,12 +57,25 @@ public class PrivacyListProvider {
*/
private BlockingQueue<SAXReader> xmlReaders = new LinkedBlockingQueue<SAXReader>();
/**
* Stores the total number of privacy lists.
*/
private AtomicInteger privacyListCount;
public PrivacyListProvider() {
super();
// Initialize the pool of sax readers
for (int i=0; i<50; i++) {
xmlReaders.add(new SAXReader());
}
// Load the total number of privacy lists in the database. We're looking
// for the (very common) special case that there are no privacy lists stored.
// In that case, we can optimize away many database calls. In the future, a
// better general-case solution may be to cache all privacy lists defined
// if there are less than, say, 500.
privacyListCount = new AtomicInteger(0);
loadPrivacyListCount();
}
/**
......@@ -69,6 +86,11 @@ public class PrivacyListProvider {
* @return the names of the existing privacy lists with a default flag.
*/
public Map<String, Boolean> getPrivacyLists(String username) {
// If there are no privacy lists stored, this method is a no-op.
if (privacyListCount.get() == 0) {
return Collections.emptyMap();
}
Map<String, Boolean> names = new HashMap<String, Boolean>();
Connection con = null;
PreparedStatement pstmt = null;
......@@ -101,36 +123,59 @@ public class PrivacyListProvider {
* with the specified name does not exist.
*/
public PrivacyList loadPrivacyList(String username, String listName) {
PrivacyList privacyList = null;
java.sql.Connection con = null;
// If there are no privacy lists stored, this method is a no-op.
if (privacyListCount.get() == 0) {
return null;
}
boolean isDefault = false;
String listValue = null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
SAXReader xmlReader = null;
try {
// Get a sax reader from the pool
xmlReader = xmlReaders.take();
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_PRIVACY_LIST);
pstmt.setString(1, username);
pstmt.setString(2, listName);
rs = pstmt.executeQuery();
while (rs.next()) {
boolean isDefault = rs.getInt(1) == 1;
Element listElement =
xmlReader.read(new StringReader(rs.getString(2))).getRootElement();
privacyList = new PrivacyList(username, listName, isDefault, listElement);
if (rs.next()) {
isDefault = rs.getInt(1) == 1;
listValue = rs.getString(2);
}
else {
return null;
}
}
catch (Exception e) {
Log.error("Error loading privacy list: " + listName + " of username: " + username, e);
return null;
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
PrivacyList privacyList = null;
SAXReader xmlReader = null;
try {
// Get a sax reader from the pool
xmlReader = xmlReaders.take();
Element listElement = xmlReader.read(new StringReader(listValue)).getRootElement();
privacyList = new PrivacyList(username, listName, isDefault, listElement);
}
catch (Exception e) {
Log.error(e);
}
finally {
// Return the sax reader to the pool
if (xmlReader != null) {
xmlReaders.add(xmlReader);
}
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return privacyList;
}
......@@ -142,35 +187,56 @@ public class PrivacyListProvider {
* @return the default privacy list or <tt>null</tt> if no list was found.
*/
public PrivacyList loadDefaultPrivacyList(String username) {
PrivacyList privacyList = null;
java.sql.Connection con = null;
// If there are no privacy lists stored, this method is a no-op.
if (privacyListCount.get() == 0) {
return null;
}
String listName = null;
String listValue = null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
SAXReader xmlReader = null;
try {
// Get a sax reader from the pool
xmlReader = xmlReaders.take();
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_DEFAULT_PRIVACY_LIST);
pstmt.setString(1, username);
rs = pstmt.executeQuery();
while (rs.next()) {
String listName= rs.getString(1);
Element listElement =
xmlReader.read(new StringReader(rs.getString(2))).getRootElement();
privacyList = new PrivacyList(username, listName, true, listElement);
if (rs.next()) {
listName = rs.getString(1);
listValue = rs.getString(2);
}
else {
return null;
}
}
catch (Exception e) {
Log.error("Error loading default privacy list of username: " + username, e);
return null;
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
PrivacyList privacyList = null;
SAXReader xmlReader = null;
try {
// Get a sax reader from the pool
xmlReader = xmlReaders.take();
Element listElement = xmlReader.read(new StringReader(listValue)).getRootElement();
privacyList = new PrivacyList(username, listName, true, listElement);
}
catch (Exception e) {
Log.error(e);
}
finally {
// Return the sax reader to the pool
if (xmlReader != null) {
xmlReaders.add(xmlReader);
}
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return privacyList;
}
......@@ -199,6 +265,9 @@ public class PrivacyListProvider {
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
// Set the privacy list count to -1. We don't know how many privacy lists there
// are, but it's not "0", which is the case we care about.
privacyListCount.set(-1);
}
/**
......@@ -220,9 +289,8 @@ public class PrivacyListProvider {
pstmt.executeUpdate();
}
catch (Exception e) {
Log.error(
"Error updating privacy list: " + list.getName() + " of username: " + username,
e);
Log.error("Error updating privacy list: " + list.getName() + " of username: " +
username, e);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
......@@ -236,6 +304,10 @@ public class PrivacyListProvider {
* @param listName the name of the PrivacyList to delete.
*/
public void deletePrivacyList(String username, String listName) {
// If there are no privacy lists stored, this method is a no-op.
if (privacyListCount.get() == 0) {
return;
}
Connection con = null;
PreparedStatement pstmt = null;
try {
......@@ -251,6 +323,9 @@ public class PrivacyListProvider {
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
// Set the privacy list count to -1. We don't know how many privacy lists there
// are, but it's probably not "0", which is the case we care about.
privacyListCount.set(-1);
}
/**
......@@ -259,6 +334,10 @@ public class PrivacyListProvider {
* @param username the username of the user whose privacy lists are going to be deleted.
*/
public void deletePrivacyLists(String username) {
// If there are no privacy lists stored, this method is a no-op.
if (privacyListCount.get() == 0) {
return;
}
Connection con = null;
PreparedStatement pstmt = null;
try {
......@@ -273,5 +352,30 @@ public class PrivacyListProvider {
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
// Set the privacy list count to -1. We don't know how many privacy lists there
// are, but it's probably not "0", which is the case we care about.
privacyListCount.set(-1);
}
/**
* Loads the total number of privacy lists stored in the database.
*/
private void loadPrivacyListCount() {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(PRIVACY_LIST_COUNT);
rs = pstmt.executeQuery();
rs.next();
privacyListCount.set(rs.getInt(1));
}
catch (Exception e) {
Log.error(e);
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment