Merge branch '625-avoid-repeated-author-status-lookups' into 'master'

Avoid repeated author status lookups

Closes #625

See merge request !322
This commit is contained in:
akwizgran
2016-09-22 13:18:45 +00:00
2 changed files with 77 additions and 30 deletions

View File

@@ -44,9 +44,11 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;
@@ -550,8 +552,6 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
new BdfEntry(KEY_TYPE, COMMENT.getInt())
);
// TODO this could be optimized by looking up author status once (#625)
Collection<BlogPostHeader> headers = new ArrayList<BlogPostHeader>();
Transaction txn = db.startTransaction(true);
try {
@@ -564,10 +564,26 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
metadata1.size() + metadata2.size());
metadata.putAll(metadata1);
metadata.putAll(metadata2);
// get all authors we need to get the status for
Set<AuthorId> authors = new HashSet<AuthorId>();
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
authors.add(new AuthorId(
entry.getValue().getDictionary(KEY_AUTHOR)
.getRaw(KEY_AUTHOR_ID)));
}
// get statuses for all authors
Map<AuthorId, Status> authorStatuses =
new HashMap<AuthorId, Status>();
for (AuthorId authorId : authors) {
authorStatuses.put(authorId,
identityManager.getAuthorStatus(txn, authorId));
}
// get post headers
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
BdfDictionary meta = entry.getValue();
BlogPostHeader h =
getPostHeaderFromMetadata(txn, g, entry.getKey(), meta);
getPostHeaderFromMetadata(txn, g, entry.getKey(), meta,
authorStatuses);
headers.add(h);
}
txn.setComplete();
@@ -611,6 +627,14 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
private BlogPostHeader getPostHeaderFromMetadata(Transaction txn,
GroupId groupId, MessageId id, BdfDictionary meta)
throws DbException, FormatException {
return getPostHeaderFromMetadata(txn, groupId, id, meta,
Collections.<AuthorId, Status>emptyMap());
}
private BlogPostHeader getPostHeaderFromMetadata(Transaction txn,
GroupId groupId, MessageId id, BdfDictionary meta,
Map<AuthorId, Status> authorStatuses)
throws DbException, FormatException {
MessageType type = getMessageType(meta);
@@ -622,7 +646,12 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
String name = d.getString(KEY_AUTHOR_NAME);
byte[] publicKey = d.getRaw(KEY_PUBLIC_KEY);
Author author = new Author(authorId, name, publicKey);
Status authorStatus = identityManager.getAuthorStatus(txn, authorId);
Status authorStatus;
if (authorStatuses.containsKey(authorId)) {
authorStatus = authorStatuses.get(authorId);
} else {
authorStatus = identityManager.getAuthorStatus(txn, authorId);
}
boolean read = meta.getBoolean(KEY_READ, false);

View File

@@ -29,9 +29,12 @@ import org.briarproject.util.StringUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject;
@@ -192,23 +195,38 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
public Collection<ForumPostHeader> getPostHeaders(GroupId g)
throws DbException {
Map<MessageId, BdfDictionary> metadata;
Collection<ForumPostHeader> headers = new ArrayList<ForumPostHeader>();
Transaction txn = db.startTransaction(true);
try {
metadata = clientHelper.getMessageMetadataAsDictionary(g);
Map<MessageId, BdfDictionary> metadata =
clientHelper.getMessageMetadataAsDictionary(txn, g);
// get all authors we need to get the status for
Set<AuthorId> authors = new HashSet<AuthorId>();
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
BdfDictionary d =
entry.getValue().getDictionary(KEY_AUTHOR, null);
if (d != null)
authors.add(new AuthorId(d.getRaw(KEY_ID)));
}
// get statuses for all authors
Map<AuthorId, Status> statuses = new HashMap<AuthorId, Status>();
for (AuthorId id : authors) {
statuses.put(id, identityManager.getAuthorStatus(txn, id));
}
// Parse the metadata
for (Entry<MessageId, BdfDictionary> entry : metadata
.entrySet()) {
BdfDictionary meta = entry.getValue();
headers.add(getForumPostHeader(txn, entry.getKey(), meta,
statuses));
}
txn.setComplete();
return headers;
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
// Parse the metadata
Collection<ForumPostHeader> headers = new ArrayList<ForumPostHeader>();
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
try {
BdfDictionary meta = entry.getValue();
headers.add(getForumPostHeader(entry.getKey(), meta));
} catch (FormatException e) {
throw new DbException(e);
}
}
return headers;
}
@Override
@@ -236,10 +254,17 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
private ForumPostHeader getForumPostHeader(Transaction txn, MessageId id,
BdfDictionary meta) throws DbException, FormatException {
return getForumPostHeader(txn, id, meta,
Collections.<AuthorId, Status>emptyMap());
}
private ForumPostHeader getForumPostHeader(Transaction txn, MessageId id,
BdfDictionary meta, Map<AuthorId, Status> statuses)
throws DbException, FormatException {
long timestamp = meta.getLong(KEY_TIMESTAMP);
Author author = null;
Status authorStatus = ANONYMOUS;
Status status = ANONYMOUS;
MessageId parentId = null;
if (meta.containsKey(KEY_PARENT))
parentId = new MessageId(meta.getRaw(KEY_PARENT));
@@ -249,23 +274,16 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
String name = d1.getString(KEY_NAME);
byte[] publicKey = d1.getRaw(KEY_PUBLIC_NAME);
author = new Author(authorId, name, publicKey);
if (txn == null) {
authorStatus = identityManager.getAuthorStatus(author.getId());
if (statuses.containsKey(authorId)) {
status = statuses.get(authorId);
} else {
authorStatus =
identityManager.getAuthorStatus(txn, author.getId());
status = identityManager.getAuthorStatus(txn, author.getId());
}
}
boolean read = meta.getBoolean(KEY_READ);
return new ForumPostHeader(id, parentId, timestamp, author,
authorStatus, read);
}
private ForumPostHeader getForumPostHeader(MessageId id,
BdfDictionary meta) throws DbException, FormatException {
return getForumPostHeader(null, id, meta);
return new ForumPostHeader(id, parentId, timestamp, author, status,
read);
}
}