mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 14:19:53 +01:00
Load list of private groups in a single DB transaction
This commit is contained in:
@@ -14,6 +14,7 @@ import org.briarproject.bramble.api.contact.ContactManager;
|
|||||||
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
||||||
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
|
import org.briarproject.bramble.api.db.TransactionManager;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
||||||
@@ -85,6 +86,8 @@ public interface AndroidComponent
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
Executor databaseExecutor();
|
Executor databaseExecutor();
|
||||||
|
|
||||||
|
TransactionManager transactionManager();
|
||||||
|
|
||||||
MessageTracker messageTracker();
|
MessageTracker messageTracker();
|
||||||
|
|
||||||
LifecycleManager lifecycleManager();
|
LifecycleManager lifecycleManager();
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import org.briarproject.bramble.api.contact.ContactManager;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
||||||
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.db.TransactionManager;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
@@ -55,6 +57,7 @@ class GroupListControllerImpl extends DbControllerImpl
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(GroupListControllerImpl.class.getName());
|
Logger.getLogger(GroupListControllerImpl.class.getName());
|
||||||
|
|
||||||
|
private final TransactionManager db;
|
||||||
private final PrivateGroupManager groupManager;
|
private final PrivateGroupManager groupManager;
|
||||||
private final GroupInvitationManager groupInvitationManager;
|
private final GroupInvitationManager groupInvitationManager;
|
||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
@@ -67,11 +70,14 @@ class GroupListControllerImpl extends DbControllerImpl
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GroupListControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
GroupListControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||||
LifecycleManager lifecycleManager, PrivateGroupManager groupManager,
|
LifecycleManager lifecycleManager,
|
||||||
|
TransactionManager db,
|
||||||
|
PrivateGroupManager groupManager,
|
||||||
GroupInvitationManager groupInvitationManager,
|
GroupInvitationManager groupInvitationManager,
|
||||||
ContactManager contactManager,
|
ContactManager contactManager,
|
||||||
AndroidNotificationManager notificationManager, EventBus eventBus) {
|
AndroidNotificationManager notificationManager, EventBus eventBus) {
|
||||||
super(dbExecutor, lifecycleManager);
|
super(dbExecutor, lifecycleManager);
|
||||||
|
this.db = db;
|
||||||
this.groupManager = groupManager;
|
this.groupManager = groupManager;
|
||||||
this.groupInvitationManager = groupInvitationManager;
|
this.groupInvitationManager = groupInvitationManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
@@ -140,32 +146,7 @@ class GroupListControllerImpl extends DbControllerImpl
|
|||||||
ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {
|
ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {
|
||||||
runOnDbThread(() -> {
|
runOnDbThread(() -> {
|
||||||
try {
|
try {
|
||||||
long start = now();
|
db.transaction(true, txn -> loadGroups(txn, handler));
|
||||||
Collection<PrivateGroup> groups =
|
|
||||||
groupManager.getPrivateGroups();
|
|
||||||
List<GroupItem> items = new ArrayList<>(groups.size());
|
|
||||||
Map<AuthorId, AuthorInfo> authorInfos = new HashMap<>();
|
|
||||||
for (PrivateGroup g : groups) {
|
|
||||||
try {
|
|
||||||
GroupId id = g.getId();
|
|
||||||
AuthorId authorId = g.getCreator().getId();
|
|
||||||
AuthorInfo authorInfo;
|
|
||||||
if (authorInfos.containsKey(authorId)) {
|
|
||||||
authorInfo = authorInfos.get(authorId);
|
|
||||||
} else {
|
|
||||||
authorInfo = contactManager.getAuthorInfo(authorId);
|
|
||||||
authorInfos.put(authorId, authorInfo);
|
|
||||||
}
|
|
||||||
GroupCount count = groupManager.getGroupCount(id);
|
|
||||||
boolean dissolved = groupManager.isDissolved(id);
|
|
||||||
items.add(
|
|
||||||
new GroupItem(g, authorInfo, count, dissolved));
|
|
||||||
} catch (NoSuchGroupException e) {
|
|
||||||
// Continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logDuration(LOG, "Loading groups", start);
|
|
||||||
handler.onResult(items);
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
handler.onException(e);
|
handler.onException(e);
|
||||||
@@ -173,6 +154,36 @@ class GroupListControllerImpl extends DbControllerImpl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DatabaseExecutor
|
||||||
|
private void loadGroups(Transaction txn,
|
||||||
|
ResultExceptionHandler<Collection<GroupItem>, DbException> handler)
|
||||||
|
throws DbException {
|
||||||
|
long start = now();
|
||||||
|
Collection<PrivateGroup> groups = groupManager.getPrivateGroups(txn);
|
||||||
|
List<GroupItem> items = new ArrayList<>(groups.size());
|
||||||
|
Map<AuthorId, AuthorInfo> authorInfos = new HashMap<>();
|
||||||
|
for (PrivateGroup g : groups) {
|
||||||
|
try {
|
||||||
|
GroupId id = g.getId();
|
||||||
|
AuthorId authorId = g.getCreator().getId();
|
||||||
|
AuthorInfo authorInfo;
|
||||||
|
if (authorInfos.containsKey(authorId)) {
|
||||||
|
authorInfo = authorInfos.get(authorId);
|
||||||
|
} else {
|
||||||
|
authorInfo = contactManager.getAuthorInfo(txn, authorId);
|
||||||
|
authorInfos.put(authorId, authorInfo);
|
||||||
|
}
|
||||||
|
GroupCount count = groupManager.getGroupCount(txn, id);
|
||||||
|
boolean dissolved = groupManager.isDissolved(txn, id);
|
||||||
|
items.add(new GroupItem(g, authorInfo, count, dissolved));
|
||||||
|
} catch (NoSuchGroupException e) {
|
||||||
|
// Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logDuration(LOG, "Loading groups", start);
|
||||||
|
handler.onResult(items);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeGroup(GroupId g, ExceptionHandler<DbException> handler) {
|
public void removeGroup(GroupId g, ExceptionHandler<DbException> handler) {
|
||||||
runOnDbThread(() -> {
|
runOnDbThread(() -> {
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ public interface PrivateGroupManager {
|
|||||||
*/
|
*/
|
||||||
void markGroupDissolved(Transaction txn, GroupId g) throws DbException;
|
void markGroupDissolved(Transaction txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given private group has been dissolved.
|
||||||
|
*/
|
||||||
|
boolean isDissolved(Transaction txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given private group has been dissolved.
|
* Returns true if the given private group has been dissolved.
|
||||||
*/
|
*/
|
||||||
@@ -91,6 +96,12 @@ public interface PrivateGroupManager {
|
|||||||
*/
|
*/
|
||||||
Collection<PrivateGroup> getPrivateGroups() throws DbException;
|
Collection<PrivateGroup> getPrivateGroups() throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all private groups the user is a member of.
|
||||||
|
*/
|
||||||
|
Collection<PrivateGroup> getPrivateGroups(Transaction txn)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the text of the private group message with the given ID.
|
* Returns the text of the private group message with the given ID.
|
||||||
*/
|
*/
|
||||||
@@ -111,6 +122,11 @@ public interface PrivateGroupManager {
|
|||||||
*/
|
*/
|
||||||
boolean isMember(Transaction txn, GroupId g, Author a) throws DbException;
|
boolean isMember(Transaction txn, GroupId g, Author a) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the group count for the given private group.
|
||||||
|
*/
|
||||||
|
GroupCount getGroupCount(Transaction txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the group count for the given private group.
|
* Returns the group count for the given private group.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -270,22 +270,31 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PrivateGroup> getPrivateGroups() throws DbException {
|
public Collection<PrivateGroup> getPrivateGroups(Transaction txn)
|
||||||
Collection<Group> groups;
|
throws DbException {
|
||||||
Transaction txn = db.startTransaction(true);
|
Collection<Group> groups = db.getGroups(txn, CLIENT_ID, MAJOR_VERSION);
|
||||||
|
Collection<PrivateGroup> privateGroups = new ArrayList<>(groups.size());
|
||||||
try {
|
try {
|
||||||
groups = db.getGroups(txn, CLIENT_ID, MAJOR_VERSION);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Collection<PrivateGroup> privateGroups =
|
|
||||||
new ArrayList<>(groups.size());
|
|
||||||
for (Group g : groups) {
|
for (Group g : groups) {
|
||||||
privateGroups.add(privateGroupFactory.parsePrivateGroup(g));
|
privateGroups.add(privateGroupFactory.parsePrivateGroup(g));
|
||||||
}
|
}
|
||||||
return privateGroups;
|
} catch (FormatException e) {
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
return privateGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PrivateGroup> getPrivateGroups() throws DbException {
|
||||||
|
return db.transactionWithResult(true, this::getPrivateGroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDissolved(Transaction txn, GroupId g) throws DbException {
|
||||||
|
try {
|
||||||
|
BdfDictionary meta =
|
||||||
|
clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||||
|
return meta.getBoolean(GROUP_KEY_DISSOLVED);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -293,12 +302,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDissolved(GroupId g) throws DbException {
|
public boolean isDissolved(GroupId g) throws DbException {
|
||||||
try {
|
return db.transactionWithResult(true, txn -> isDissolved(txn, g));
|
||||||
BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(g);
|
|
||||||
return meta.getBoolean(GROUP_KEY_DISSOLVED);
|
|
||||||
} catch (FormatException e) {
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -403,7 +407,8 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
PrivateGroup privateGroup = getPrivateGroup(txn, g);
|
PrivateGroup privateGroup = getPrivateGroup(txn, g);
|
||||||
for (Entry<Author, Visibility> m : authors.entrySet()) {
|
for (Entry<Author, Visibility> m : authors.entrySet()) {
|
||||||
Author a = m.getKey();
|
Author a = m.getKey();
|
||||||
AuthorInfo authorInfo = contactManager.getAuthorInfo(txn, a.getId());
|
AuthorInfo authorInfo =
|
||||||
|
contactManager.getAuthorInfo(txn, a.getId());
|
||||||
Status status = authorInfo.getStatus();
|
Status status = authorInfo.getStatus();
|
||||||
Visibility v = m.getValue();
|
Visibility v = m.getValue();
|
||||||
ContactId c = null;
|
ContactId c = null;
|
||||||
@@ -450,6 +455,12 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupCount getGroupCount(Transaction txn, GroupId g)
|
||||||
|
throws DbException {
|
||||||
|
return messageTracker.getGroupCount(txn, g);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GroupCount getGroupCount(GroupId g) throws DbException {
|
public GroupCount getGroupCount(GroupId g) throws DbException {
|
||||||
return messageTracker.getGroupCount(g);
|
return messageTracker.getGroupCount(g);
|
||||||
|
|||||||
Reference in New Issue
Block a user