less database calls

This commit is contained in:
Athou
2013-07-23 16:19:19 +02:00
parent 150920e0c8
commit d95e1522d8
3 changed files with 51 additions and 39 deletions

View File

@@ -17,6 +17,7 @@ import javax.persistence.criteria.Root;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Disjunction; import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order; import org.hibernate.criterion.Order;
@@ -50,17 +51,23 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
protected static Logger log = LoggerFactory protected static Logger log = LoggerFactory
.getLogger(FeedEntryStatusDAO.class); .getLogger(FeedEntryStatusDAO.class);
private static final Comparator<FeedEntry> ENTRY_COMPARATOR_DESC = new Comparator<FeedEntry>() { private static final String ALIAS_STATUS = "status";
private static final String ALIAS_ENTRY = "entry";
private static final String ALIAS_FFE = "ffe";
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_DESC = new Comparator<FeedEntryStatus>() {
@Override @Override
public int compare(FeedEntry o1, FeedEntry o2) { public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
return ObjectUtils.compare(o2.getUpdated(), o1.getUpdated()); return ObjectUtils.compare(o2.getEntryUpdated(),
o1.getEntryUpdated());
}; };
}; };
private static final Comparator<FeedEntry> ENTRY_COMPARATOR_ASC = new Comparator<FeedEntry>() { private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = new Comparator<FeedEntryStatus>() {
@Override @Override
public int compare(FeedEntry o1, FeedEntry o2) { public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
return ObjectUtils.compare(o1.getUpdated(), o2.getUpdated()); return ObjectUtils.compare(o1.getEntryUpdated(),
o2.getEntryUpdated());
}; };
}; };
@@ -80,6 +87,12 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
List<FeedEntryStatus> statuses = em.createQuery(query).getResultList(); List<FeedEntryStatus> statuses = em.createQuery(query).getResultList();
FeedEntryStatus status = Iterables.getFirst(statuses, null); FeedEntryStatus status = Iterables.getFirst(statuses, null);
return handleStatus(status, sub, entry);
}
private FeedEntryStatus handleStatus(FeedEntryStatus status,
FeedSubscription sub, FeedEntry entry) {
if (status == null) { if (status == null) {
Date unreadThreshold = getUnreadThreshold(); Date unreadThreshold = getUnreadThreshold();
boolean read = unreadThreshold == null ? false : entry boolean read = unreadThreshold == null ? false : entry
@@ -120,13 +133,12 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
private Criteria buildSearchCriteria(FeedSubscription sub, private Criteria buildSearchCriteria(FeedSubscription sub,
boolean unreadOnly, String keywords, Date newerThan, int offset, boolean unreadOnly, String keywords, Date newerThan, int offset,
int limit, ReadingOrder order, boolean includeContent, int limit, ReadingOrder order, boolean includeContent, Date last) {
FeedEntry last) {
Criteria criteria = getSession().createCriteria(FeedEntry.class, Criteria criteria = getSession().createCriteria(FeedEntry.class,
"entry"); ALIAS_ENTRY);
Criteria ffeJoin = criteria.createCriteria( Criteria ffeJoin = criteria.createCriteria(
FeedEntry_.feedRelationships.getName(), "ffe", FeedEntry_.feedRelationships.getName(), ALIAS_FFE,
JoinType.INNER_JOIN); JoinType.INNER_JOIN);
ffeJoin.add(Restrictions.eq(FeedFeedEntry_.feed.getName(), ffeJoin.add(Restrictions.eq(FeedFeedEntry_.feed.getName(),
sub.getFeed())); sub.getFeed()));
@@ -153,7 +165,7 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
if (unreadOnly) { if (unreadOnly) {
Criteria statusJoin = criteria.createCriteria(FeedEntry_.statuses Criteria statusJoin = criteria.createCriteria(FeedEntry_.statuses
.getName(), "status", JoinType.LEFT_OUTER_JOIN, .getName(), ALIAS_STATUS, JoinType.LEFT_OUTER_JOIN,
Restrictions.eq(FeedEntryStatus_.subscription.getName(), Restrictions.eq(FeedEntryStatus_.subscription.getName(),
sub)); sub));
@@ -173,12 +185,10 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
if (last != null) { if (last != null) {
if (order == ReadingOrder.desc) { if (order == ReadingOrder.desc) {
ffeJoin.add(Restrictions.gt( ffeJoin.add(Restrictions.gt(
FeedFeedEntry_.entryUpdated.getName(), FeedFeedEntry_.entryUpdated.getName(), last));
last.getUpdated()));
} else { } else {
ffeJoin.add(Restrictions.lt( ffeJoin.add(Restrictions.lt(
FeedFeedEntry_.entryUpdated.getName(), FeedFeedEntry_.entryUpdated.getName(), last));
last.getUpdated()));
} }
} }
@@ -211,38 +221,38 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
ReadingOrder order, boolean includeContent) { ReadingOrder order, boolean includeContent) {
int capacity = offset + limit; int capacity = offset + limit;
Comparator<FeedEntry> comparator = order == ReadingOrder.desc ? ENTRY_COMPARATOR_DESC Comparator<FeedEntryStatus> comparator = order == ReadingOrder.desc ? STATUS_COMPARATOR_DESC
: ENTRY_COMPARATOR_ASC; : STATUS_COMPARATOR_ASC;
FixedSizeSortedSet<FeedEntry> set = new FixedSizeSortedSet<FeedEntry>( FixedSizeSortedSet<FeedEntryStatus> set = new FixedSizeSortedSet<FeedEntryStatus>(
capacity < 0 ? Integer.MAX_VALUE : capacity, comparator); capacity < 0 ? Integer.MAX_VALUE : capacity, comparator);
for (FeedSubscription sub : subscriptions) { for (FeedSubscription sub : subscriptions) {
FeedEntry last = (order != null && set.isFull()) ? set.last() Date last = (order != null && set.isFull()) ? set.last()
: null; .getEntryUpdated() : null;
Criteria criteria = buildSearchCriteria(sub, unreadOnly, keywords, Criteria criteria = buildSearchCriteria(sub, unreadOnly, keywords,
newerThan, -1, limit, order, includeContent, last); newerThan, -1, limit, order, includeContent, last);
criteria.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
List<FeedEntry> list = criteria.list(); List<Map<String, Object>> list = criteria.list();
for (FeedEntry entry : list) { for (Map<String, Object> map : list) {
FeedEntryStatus status = (FeedEntryStatus) map
.get(ALIAS_STATUS);
FeedEntry entry = (FeedEntry) map.get(ALIAS_ENTRY);
entry.setSubscription(sub); entry.setSubscription(sub);
status = handleStatus(status, sub, entry);
status.setEntry(entry);
set.add(status);
} }
set.addAll(list);
} }
List<FeedEntry> entries = set.asList(); List<FeedEntryStatus> statuses = set.asList();
int size = entries.size(); int size = statuses.size();
if (size < offset) { if (size < offset) {
return Lists.newArrayList(); return Lists.newArrayList();
} }
entries = entries.subList(Math.max(offset, 0), size); statuses = statuses.subList(Math.max(offset, 0), size);
return lazyLoadContent(includeContent, statuses);
List<FeedEntryStatus> results = Lists.newArrayList();
for (FeedEntry entry : entries) {
FeedSubscription subscription = entry.getSubscription();
results.add(getStatus(subscription, entry));
}
return lazyLoadContent(includeContent, results);
} }
private Date getUnreadThreshold() { private Date getUnreadThreshold() {

View File

@@ -37,7 +37,6 @@ public class FeedEntryService {
} }
FeedEntryStatus status = feedEntryStatusDAO.getStatus(sub, entry); FeedEntryStatus status = feedEntryStatusDAO.getStatus(sub, entry);
status.setRead(read); status.setRead(read);
feedEntryStatusDAO.saveOrUpdate(status); feedEntryStatusDAO.saveOrUpdate(status);
} }
@@ -57,7 +56,6 @@ public class FeedEntryService {
} }
FeedEntryStatus status = feedEntryStatusDAO.getStatus(sub, entry); FeedEntryStatus status = feedEntryStatusDAO.getStatus(sub, entry);
status.setStarred(starred); status.setStarred(starred);
feedEntryStatusDAO.saveOrUpdate(status); feedEntryStatusDAO.saveOrUpdate(status);

View File

@@ -9,4 +9,8 @@
<query>delete from FeedEntryStatus s where s.entryInserted &lt; :date and s.starred = false</query> <query>delete from FeedEntryStatus s where s.entryInserted &lt; :date and s.starred = false</query>
</named-query> </named-query>
<named-query name="EntryStatus.existing">
<query>select new com.commafeed.backend.dao.FeedEntryDAO$EntryWithFeed(e, f) FROM FeedEntry e LEFT JOIN e.feedRelationships f WITH f.feed.id = :feedId where e.guidHash = :guidHash and e.url = :url</query>
</named-query>
</entity-mappings> </entity-mappings>