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; ...@@ -22,8 +22,10 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Collections;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Provider for the privacy lists system. Privacy lists are read and written * Provider for the privacy lists system. Privacy lists are read and written
...@@ -33,6 +35,8 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -33,6 +35,8 @@ import java.util.concurrent.LinkedBlockingQueue;
*/ */
public class PrivacyListProvider { public class PrivacyListProvider {
private static final String PRIVACY_LIST_COUNT =
"SELECT count(*) from jivePrivacyList";
private static final String LOAD_LIST_NAMES = private static final String LOAD_LIST_NAMES =
"SELECT name, isDefault FROM jivePrivacyList WHERE username=?"; "SELECT name, isDefault FROM jivePrivacyList WHERE username=?";
private static final String LOAD_PRIVACY_LIST = private static final String LOAD_PRIVACY_LIST =
...@@ -53,12 +57,25 @@ public class PrivacyListProvider { ...@@ -53,12 +57,25 @@ public class PrivacyListProvider {
*/ */
private BlockingQueue<SAXReader> xmlReaders = new LinkedBlockingQueue<SAXReader>(); private BlockingQueue<SAXReader> xmlReaders = new LinkedBlockingQueue<SAXReader>();
/**
* Stores the total number of privacy lists.
*/
private AtomicInteger privacyListCount;
public PrivacyListProvider() { public PrivacyListProvider() {
super(); super();
// Initialize the pool of sax readers // Initialize the pool of sax readers
for (int i=0; i<50; i++) { for (int i=0; i<50; i++) {
xmlReaders.add(new SAXReader()); 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 { ...@@ -69,6 +86,11 @@ public class PrivacyListProvider {
* @return the names of the existing privacy lists with a default flag. * @return the names of the existing privacy lists with a default flag.
*/ */
public Map<String, Boolean> getPrivacyLists(String username) { 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>(); Map<String, Boolean> names = new HashMap<String, Boolean>();
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
...@@ -101,36 +123,59 @@ public class PrivacyListProvider { ...@@ -101,36 +123,59 @@ public class PrivacyListProvider {
* with the specified name does not exist. * with the specified name does not exist.
*/ */
public PrivacyList loadPrivacyList(String username, String listName) { public PrivacyList loadPrivacyList(String username, String listName) {
PrivacyList privacyList = null; // If there are no privacy lists stored, this method is a no-op.
java.sql.Connection con = null; if (privacyListCount.get() == 0) {
return null;
}
boolean isDefault = false;
String listValue = null;
Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
SAXReader xmlReader = null;
try { try {
// Get a sax reader from the pool
xmlReader = xmlReaders.take();
con = DbConnectionManager.getConnection(); con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_PRIVACY_LIST); pstmt = con.prepareStatement(LOAD_PRIVACY_LIST);
pstmt.setString(1, username); pstmt.setString(1, username);
pstmt.setString(2, listName); pstmt.setString(2, listName);
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
while (rs.next()) { if (rs.next()) {
boolean isDefault = rs.getInt(1) == 1; isDefault = rs.getInt(1) == 1;
Element listElement = listValue = rs.getString(2);
xmlReader.read(new StringReader(rs.getString(2))).getRootElement(); }
privacyList = new PrivacyList(username, listName, isDefault, listElement); else {
return null;
} }
} }
catch (Exception e) { catch (Exception e) {
Log.error("Error loading privacy list: " + listName + " of username: " + username, 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 { finally {
// Return the sax reader to the pool // Return the sax reader to the pool
if (xmlReader != null) { if (xmlReader != null) {
xmlReaders.add(xmlReader); xmlReaders.add(xmlReader);
} }
DbConnectionManager.closeConnection(rs, pstmt, con);
} }
return privacyList; return privacyList;
} }
...@@ -142,35 +187,56 @@ public class PrivacyListProvider { ...@@ -142,35 +187,56 @@ public class PrivacyListProvider {
* @return the default privacy list or <tt>null</tt> if no list was found. * @return the default privacy list or <tt>null</tt> if no list was found.
*/ */
public PrivacyList loadDefaultPrivacyList(String username) { public PrivacyList loadDefaultPrivacyList(String username) {
PrivacyList privacyList = null; // If there are no privacy lists stored, this method is a no-op.
java.sql.Connection con = null; if (privacyListCount.get() == 0) {
return null;
}
String listName = null;
String listValue = null;
Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
SAXReader xmlReader = null;
try { try {
// Get a sax reader from the pool
xmlReader = xmlReaders.take();
con = DbConnectionManager.getConnection(); con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_DEFAULT_PRIVACY_LIST); pstmt = con.prepareStatement(LOAD_DEFAULT_PRIVACY_LIST);
pstmt.setString(1, username); pstmt.setString(1, username);
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
while (rs.next()) { if (rs.next()) {
String listName= rs.getString(1); listName = rs.getString(1);
Element listElement = listValue = rs.getString(2);
xmlReader.read(new StringReader(rs.getString(2))).getRootElement(); }
privacyList = new PrivacyList(username, listName, true, listElement); else {
return null;
} }
} }
catch (Exception e) { catch (Exception e) {
Log.error("Error loading default privacy list of username: " + username, 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 { finally {
// Return the sax reader to the pool // Return the sax reader to the pool
if (xmlReader != null) { if (xmlReader != null) {
xmlReaders.add(xmlReader); xmlReaders.add(xmlReader);
} }
DbConnectionManager.closeConnection(rs, pstmt, con);
} }
return privacyList; return privacyList;
} }
...@@ -199,6 +265,9 @@ public class PrivacyListProvider { ...@@ -199,6 +265,9 @@ public class PrivacyListProvider {
finally { finally {
DbConnectionManager.closeConnection(pstmt, con); 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 { ...@@ -220,9 +289,8 @@ public class PrivacyListProvider {
pstmt.executeUpdate(); pstmt.executeUpdate();
} }
catch (Exception e) { catch (Exception e) {
Log.error( Log.error("Error updating privacy list: " + list.getName() + " of username: " +
"Error updating privacy list: " + list.getName() + " of username: " + username, username, e);
e);
} }
finally { finally {
DbConnectionManager.closeConnection(pstmt, con); DbConnectionManager.closeConnection(pstmt, con);
...@@ -236,6 +304,10 @@ public class PrivacyListProvider { ...@@ -236,6 +304,10 @@ public class PrivacyListProvider {
* @param listName the name of the PrivacyList to delete. * @param listName the name of the PrivacyList to delete.
*/ */
public void deletePrivacyList(String username, String listName) { 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; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
...@@ -251,6 +323,9 @@ public class PrivacyListProvider { ...@@ -251,6 +323,9 @@ public class PrivacyListProvider {
finally { finally {
DbConnectionManager.closeConnection(pstmt, con); 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 { ...@@ -259,6 +334,10 @@ public class PrivacyListProvider {
* @param username the username of the user whose privacy lists are going to be deleted. * @param username the username of the user whose privacy lists are going to be deleted.
*/ */
public void deletePrivacyLists(String username) { 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; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
...@@ -273,5 +352,30 @@ public class PrivacyListProvider { ...@@ -273,5 +352,30 @@ public class PrivacyListProvider {
finally { finally {
DbConnectionManager.closeConnection(pstmt, con); 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